From b54c61e30361e1e2bc4ec6441e13baef22212bb2 Mon Sep 17 00:00:00 2001 From: Ian Forbes Date: Wed, 23 Nov 2022 11:20:16 -0600 Subject: [PATCH] Fix clone3 crash in glibc 2.34+ glibc has been using clone3 internally since commit d8ea0d0168b190bdf138a20358293c939509367f. --- src/intercept.c | 11 ++++++++++- test/hook_test_clone_preload.c | 6 +++++- test/test_clone_thread_preload.c | 11 +++++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/intercept.c b/src/intercept.c index 9600ad8d..efda03a8 100644 --- a/src/intercept.c +++ b/src/intercept.c @@ -52,6 +52,7 @@ #include #include #include +#include #include "intercept.h" #include "intercept_log.h" @@ -675,9 +676,17 @@ intercept_routine(struct context *context) * the clone_child_intercept_routine instead, executing * it on the new child threads stack, then returns to libc. */ - if (desc.nr == SYS_clone && desc.args[1] != 0) + 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 && + ((struct clone_args *)desc.args[0])->stack != 0) { + return (struct wrapper_ret){ + .rax = context->rax, .rdx = 2 }; + } +#endif else result = syscall_no_intercept(desc.nr, desc.args[0], diff --git a/test/hook_test_clone_preload.c b/test/hook_test_clone_preload.c index 8ab68d98..f837330b 100644 --- a/test/hook_test_clone_preload.c +++ b/test/hook_test_clone_preload.c @@ -42,7 +42,7 @@ #include #include #include - +#include #include "libsyscall_intercept_hook_point.h" static int hook_counter; @@ -65,6 +65,10 @@ hook(long syscall_number, if (syscall_number == SYS_clone) hook_counter++; +#ifdef SYS_clone3 + 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 c7663a28..de6fec87 100644 --- a/test/test_clone_thread_preload.c +++ b/test/test_clone_thread_preload.c @@ -47,6 +47,7 @@ #include #include #include +#include static long flags = -1; @@ -80,9 +81,15 @@ 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)) + 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; }