From ae6d62de0c5d13373f551a003ff0e1b65776c483 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Sun, 5 Mar 2023 19:53:08 +0900 Subject: [PATCH] Compile-in clone3() crash fix even when the glibc version is < 2.34 Commit merged in https://github.com/pmem/syscall_intercept/pull/123 fixes clone3() crashes on glibc 2.34+. However, with the `#ifdef SYS_clone3` guard, libsyscall_intercept.so built with glibc < 2.34 will not work with 2.34+. Fix this by integrating the relevant parts from the linux and glibc headers directly. Signed-off-by: Juhyung Park --- include/libsyscall_intercept_hook_point.h | 23 +++++++++++++++++++++++ src/intercept.c | 8 ++------ test/hook_test_clone_preload.c | 4 +--- test/test_clone_thread_preload.c | 4 ++-- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/include/libsyscall_intercept_hook_point.h b/include/libsyscall_intercept_hook_point.h index 2fe7d57c..e78618bf 100644 --- a/include/libsyscall_intercept_hook_point.h +++ b/include/libsyscall_intercept_hook_point.h @@ -95,6 +95,29 @@ syscall_error_code(long result) */ int syscall_hook_in_process_allowed(void); +/* + * glibc has been using clone3() internally since commit d8ea0d0168b190b. + * Make sure recent versions of glibc work properly even when this library + * is built with older verions of glibc. + */ +#ifndef SYS_clone3 +#define SYS_clone3 435 +#include +struct clone_args { + __aligned_u64 flags; + __aligned_u64 pidfd; + __aligned_u64 child_tid; + __aligned_u64 parent_tid; + __aligned_u64 exit_signal; + __aligned_u64 stack; + __aligned_u64 stack_size; + __aligned_u64 tls; + __aligned_u64 set_tid; + __aligned_u64 set_tid_size; + __aligned_u64 cgroup; +}; +#endif + #ifdef __cplusplus } #endif diff --git a/src/intercept.c b/src/intercept.c index efda03a8..e6a23df9 100644 --- a/src/intercept.c +++ b/src/intercept.c @@ -679,15 +679,11 @@ intercept_routine(struct context *context) if (desc.nr == SYS_clone && desc.args[1] != 0) { return (struct wrapper_ret){ .rax = context->rax, .rdx = 2 }; - } -#ifdef SYS_clone3 - else if (desc.nr == SYS_clone3 && + } else if (desc.nr == SYS_clone3 && ((struct clone_args *)desc.args[0])->stack != 0) { return (struct wrapper_ret){ .rax = context->rax, .rdx = 2 }; - } -#endif - else + } else result = syscall_no_intercept(desc.nr, desc.args[0], desc.args[1], diff --git a/test/hook_test_clone_preload.c b/test/hook_test_clone_preload.c index f837330b..c9a02a95 100644 --- a/test/hook_test_clone_preload.c +++ b/test/hook_test_clone_preload.c @@ -65,10 +65,8 @@ hook(long syscall_number, if (syscall_number == SYS_clone) hook_counter++; -#ifdef SYS_clone3 - if (syscall_number == SYS_clone3) + else if (syscall_number == SYS_clone3) hook_counter++; -#endif return 1; } diff --git a/test/test_clone_thread_preload.c b/test/test_clone_thread_preload.c index de6fec87..9376a659 100644 --- a/test/test_clone_thread_preload.c +++ b/test/test_clone_thread_preload.c @@ -84,12 +84,12 @@ hook(long syscall_number, if (syscall_number == SYS_clone && (arg1 != 0)) { flags = arg0; } -#ifdef SYS_clone3 + if (syscall_number == SYS_clone3 && ((struct clone_args *)arg0)->stack != 0) { flags = arg0; } -#endif + return 1; }