diff --git a/include/libsyscall_intercept_hook_point.h b/include/libsyscall_intercept_hook_point.h index 2fe7d57c..7c61a0ea 100644 --- a/include/libsyscall_intercept_hook_point.h +++ b/include/libsyscall_intercept_hook_point.h @@ -57,8 +57,12 @@ 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_parent)(long pid); +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); /* * syscall_no_intercept - syscall without interception diff --git a/src/intercept.c b/src/intercept.c index 9600ad8d..04038997 100644 --- a/src/intercept.c +++ b/src/intercept.c @@ -67,9 +67,13 @@ 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) +void (*intercept_hook_point_clone_parent)( + long *, unsigned long, unsigned long, + void *, void *, unsigned) __attribute__((visibility("default"))); bool debug_dumps_on; @@ -701,12 +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(); + intercept_hook_point_clone_child( + 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); + intercept_hook_point_clone_parent( + &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 }; diff --git a/test/test_clone_thread_preload.c b/test/test_clone_thread_preload.c index c7663a28..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; } @@ -96,11 +107,38 @@ 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) { + 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)); } @@ -109,4 +147,5 @@ init(void) { intercept_hook_point = hook; intercept_hook_point_clone_child = hook_child; + intercept_hook_point_clone_parent = hook_parent; }