From 6333d6e81e9f298c9bf7030b1bda9e906656d8f6 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 4 Apr 2009 22:42:25 -0400 Subject: libsandbox: handle trace code when vforking The make program likes to vfork() when running programs, so if it vforks and runs a static binary, we need to make sure we clean up state in the child so as to not make the parent angry. URL: http://bugs.gentoo.org/264478 Signed-off-by: Mike Frysinger Reported-by: Paul Mulders --- libsandbox/libsandbox.h | 2 ++ libsandbox/trace.c | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'libsandbox') diff --git a/libsandbox/libsandbox.h b/libsandbox/libsandbox.h index 21f94d2..d20b81f 100644 --- a/libsandbox/libsandbox.h +++ b/libsandbox/libsandbox.h @@ -70,4 +70,6 @@ char *erealpath(const char *, char *); char *egetcwd(char *, size_t); int canonicalize(const char *, char *); +#include "sbutil.h" + #endif /* __LIBSANDBOX_H__ */ diff --git a/libsandbox/trace.c b/libsandbox/trace.c index 7df9570..dd3bfb8 100644 --- a/libsandbox/trace.c +++ b/libsandbox/trace.c @@ -5,7 +5,6 @@ */ #include "headers.h" -#include "sbutil.h" #include "libsandbox.h" #include "wrappers.h" #include "sb_nr.h" @@ -125,6 +124,13 @@ static const char *strsig(int sig) } } +static void trace_exit(int status) +{ + /* if we were vfork-ed, clear trace_pid and exit */ + trace_pid = 0; + _exit(status); +} + static void trace_child_signal(int signo, siginfo_t *info, void *context) { SB_DEBUG("got sig %s(%i): code:%s(%i) status:%s(%i)", @@ -134,11 +140,11 @@ static void trace_child_signal(int signo, siginfo_t *info, void *context) switch (info->si_code) { case CLD_KILLED: - exit(128 + info->si_status); + trace_exit(128 + info->si_status); case CLD_EXITED: __SB_DEBUG(" = %i\n", info->si_status); - exit(info->si_status); + trace_exit(info->si_status); case CLD_TRAPPED: switch (info->si_status) { @@ -381,6 +387,11 @@ void trace_main(const char *filename, char *const argv[]) if (is_env_on(ENV_SANDBOX_DEBUG)) SB_EINFO("trace_main", " tracing: %s\n", filename); + if (trace_pid) { + SB_EERROR("ISE:trace_main ", "trace code assumes multiple threads are not forking\n"); + sb_abort(); + } + trace_pid = fork(); if (trace_pid == -1) { SB_EERROR("ISE:trace_main ", "vfork() failed: %s\n", -- cgit v1.2.3-18-g5258