From 6fbcf8bcb6d5890791f522914359748107e317c9 Mon Sep 17 00:00:00 2001 From: Vance Miller Date: Tue, 13 Jul 2021 13:18:02 -0700 Subject: [PATCH 1/4] Add arguments to clone_parent hook Pass through the original arguments to clone and add a pointer to the return value. This allows the hook to modify the returned PID if desired --- include/libsyscall_intercept_hook_point.h | 4 +++- src/intercept.c | 9 +++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/libsyscall_intercept_hook_point.h b/include/libsyscall_intercept_hook_point.h index 2fe7d57c..4fa8f786 100644 --- a/include/libsyscall_intercept_hook_point.h +++ b/include/libsyscall_intercept_hook_point.h @@ -58,7 +58,9 @@ extern int (*intercept_hook_point)(long syscall_number, long *result); extern void (*intercept_hook_point_clone_child)(void); -extern void (*intercept_hook_point_clone_parent)(long pid); +extern void (*intercept_hook_point_clone_parent)( + long *pid, unsigned long clone_flags, unsigned long newsp, + void *parent_tid, void *child_tid, unsigned tid); /* * syscall_no_intercept - syscall without interception diff --git a/src/intercept.c b/src/intercept.c index 9600ad8d..b2731f1d 100644 --- a/src/intercept.c +++ b/src/intercept.c @@ -69,7 +69,9 @@ int (*intercept_hook_point)(long syscall_number, void (*intercept_hook_point_clone_child)(void) __attribute__((visibility("default"))); -void (*intercept_hook_point_clone_parent)(long) +void (*intercept_hook_point_clone_parent)( + long *, unsigned long, unsigned long, + void *, void *, unsigned) __attribute__((visibility("default"))); bool debug_dumps_on; @@ -706,7 +708,10 @@ intercept_routine_post_clone(struct context *context) intercept_hook_point_clone_child(); } else { if (intercept_hook_point_clone_parent != NULL) - intercept_hook_point_clone_parent(context->rax); + intercept_hook_point_clone_parent( + &context->rax, context->rdi, context->rsi, + (void *)context->rdx, (void *)context->r10, + context->r8); } return (struct wrapper_ret){.rax = context->rax, .rdx = 1 }; From 4cf717e163a6c6c01e17dd1f5b45de1c7b223f0e Mon Sep 17 00:00:00 2001 From: Vance Miller Date: Fri, 23 Jul 2021 09:52:05 -0700 Subject: [PATCH 2/4] Clone child arguments --- include/libsyscall_intercept_hook_point.h | 4 +++- src/intercept.c | 9 +++++++-- test/test_clone_thread_preload.c | 13 ++++++++++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/include/libsyscall_intercept_hook_point.h b/include/libsyscall_intercept_hook_point.h index 4fa8f786..7c61a0ea 100644 --- a/include/libsyscall_intercept_hook_point.h +++ b/include/libsyscall_intercept_hook_point.h @@ -57,7 +57,9 @@ extern int (*intercept_hook_point)(long syscall_number, long arg4, long arg5, long *result); -extern void (*intercept_hook_point_clone_child)(void); +extern void (*intercept_hook_point_clone_child)( + unsigned long clone_flags, unsigned long newsp, + void *parent_tid, void *child_tid, unsigned tid); extern void (*intercept_hook_point_clone_parent)( long *pid, unsigned long clone_flags, unsigned long newsp, void *parent_tid, void *child_tid, unsigned tid); diff --git a/src/intercept.c b/src/intercept.c index b2731f1d..fd15b331 100644 --- a/src/intercept.c +++ b/src/intercept.c @@ -67,7 +67,9 @@ int (*intercept_hook_point)(long syscall_number, long *result) __attribute__((visibility("default"))); -void (*intercept_hook_point_clone_child)(void) +void (*intercept_hook_point_clone_child)( + unsigned long, unsigned long, + void *, void *, unsigned) __attribute__((visibility("default"))); void (*intercept_hook_point_clone_parent)( long *, unsigned long, unsigned long, @@ -705,7 +707,10 @@ intercept_routine_post_clone(struct context *context) { if (context->rax == 0) { if (intercept_hook_point_clone_child != NULL) - intercept_hook_point_clone_child(); + intercept_hook_point_clone_child( + context->rdi, context->rsi, + (void *)context->rdx, (void *)context->r10, + context->r8); } else { if (intercept_hook_point_clone_parent != NULL) intercept_hook_point_clone_parent( diff --git a/test/test_clone_thread_preload.c b/test/test_clone_thread_preload.c index c7663a28..a295a2c4 100644 --- a/test/test_clone_thread_preload.c +++ b/test/test_clone_thread_preload.c @@ -96,8 +96,19 @@ hook(long syscall_number, * of the clone syscall. */ static void -hook_child(void) +hook_child(unsigned long clone_flags, + unsigned long newsp, + void *parent_tid, + void *child_tid, + unsigned tid) { + // suppress unused warnings + (void) clone_flags; + (void) newsp; + (void) parent_tid; + (void) child_tid; + (void) tid; + static const char msg[] = "clone_hook_child called\n"; assert(flags != -1); From f367558694255d20efe98de162b36be43c073fcf Mon Sep 17 00:00:00 2001 From: Vance Miller Date: Fri, 23 Jul 2021 11:16:57 -0700 Subject: [PATCH 3/4] clone callback tests --- test/test_clone_thread_preload.c | 56 ++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/test/test_clone_thread_preload.c b/test/test_clone_thread_preload.c index a295a2c4..5c5e6cd1 100644 --- a/test/test_clone_thread_preload.c +++ b/test/test_clone_thread_preload.c @@ -33,7 +33,8 @@ /* * This library's purpose is to hook the syscalls of the program * built from test_clone_thread.c, and to check the - * intercept_hook_point_clone_child hook point while doing so. + * intercept_hook_point_clone_child and intercept_hook_point_clone_parent + * hook point while doing so. * * See also: examples/fork_ban.c about forking a new process. */ @@ -48,7 +49,15 @@ #include #include -static long flags = -1; +typedef struct { + unsigned long clone_flags; + unsigned long newsp; + void *parent_tid; + void *child_tid; + unsigned tid; +} clone_args_t; + +static clone_args_t clone_args; static int hook(long syscall_number, @@ -57,9 +66,6 @@ hook(long syscall_number, long arg4, long arg5, long *result) { - (void) arg2; - (void) arg3; - (void) arg4; (void) arg5; (void) result; @@ -80,8 +86,13 @@ hook(long syscall_number, * therefore the return value (the child's pid) can not be observed, * or modified. */ - if (syscall_number == SYS_clone && (arg1 != 0)) - flags = arg0; + if (syscall_number == SYS_clone && (arg1 != 0)) { + clone_args.clone_flags = arg0; + clone_args.newsp = arg1; + clone_args.parent_tid = (void *) arg2; + clone_args.child_tid = (void *) arg3; + clone_args.tid = arg4; + } return 1; } @@ -102,16 +113,32 @@ hook_child(unsigned long clone_flags, void *child_tid, unsigned tid) { - // suppress unused warnings - (void) clone_flags; - (void) newsp; - (void) parent_tid; - (void) child_tid; - (void) tid; static const char msg[] = "clone_hook_child called\n"; - assert(flags != -1); + assert(clone_flags == clone_args.clone_flags); + assert(newsp == clone_args.newsp); + assert(parent_tid == clone_args.parent_tid); + assert(child_tid == clone_args.child_tid); + assert(tid == clone_args.tid); + syscall_no_intercept(SYS_write, 1, msg, sizeof(msg)); +} + +static void +hook_parent(long *ret, + unsigned long clone_flags, + unsigned long newsp, + void *parent_tid, + void *child_tid, + unsigned tid) { + static const char msg[] = "clone_hook_parent called\n"; + + (void) ret; + assert(clone_flags == clone_args.clone_flags); + assert(newsp == clone_args.newsp); + assert(parent_tid == clone_args.parent_tid); + assert(child_tid == clone_args.child_tid); + assert(tid == clone_args.tid); syscall_no_intercept(SYS_write, 1, msg, sizeof(msg)); } @@ -120,4 +147,5 @@ init(void) { intercept_hook_point = hook; intercept_hook_point_clone_child = hook_child; + intercept_hook_point_clone_parent = hook_parent; } From 58e3205c884f9a90616de639c4a3d1ec702dd9b0 Mon Sep 17 00:00:00 2001 From: Vance Miller Date: Fri, 23 Jul 2021 11:31:38 -0700 Subject: [PATCH 4/4] Get syscall arguments with get_syscall_in_context function --- src/intercept.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/intercept.c b/src/intercept.c index fd15b331..04038997 100644 --- a/src/intercept.c +++ b/src/intercept.c @@ -705,18 +705,20 @@ intercept_routine(struct context *context) struct wrapper_ret intercept_routine_post_clone(struct context *context) { + struct syscall_desc desc; + get_syscall_in_context(context, &desc); if (context->rax == 0) { if (intercept_hook_point_clone_child != NULL) intercept_hook_point_clone_child( - context->rdi, context->rsi, - (void *)context->rdx, (void *)context->r10, - context->r8); + desc.args[0], desc.args[1], + (void *)desc.args[2], (void *)desc.args[3], + desc.args[4]); } else { if (intercept_hook_point_clone_parent != NULL) intercept_hook_point_clone_parent( - &context->rax, context->rdi, context->rsi, - (void *)context->rdx, (void *)context->r10, - context->r8); + &context->rax, desc.args[0], desc.args[1], + (void *)desc.args[2], (void *)desc.args[3], + desc.args[4]); } return (struct wrapper_ret){.rax = context->rax, .rdx = 1 };