From fa81508eb2d9a2a2ea69c2c585735aef7aaff97c Mon Sep 17 00:00:00 2001 From: Yawning Angel Date: Thu, 26 Mar 2015 14:56:14 +0000 Subject: [PATCH] Use prctl() to have the kernel SIGTERM background processes on exit. This uses a Linux-ism to attempt to always clean up background processes if possible. Note that it is not a catch-all, in that executables with suid/sgid or elevated capabilities will have the prctl() attribute stripped as part of the execve(). Resolves ticket 15471. --- changes/feature15471 | 5 +++++ src/common/util.c | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 changes/feature15471 diff --git a/changes/feature15471 b/changes/feature15471 new file mode 100644 index 0000000000..594adf0f54 --- /dev/null +++ b/changes/feature15471 @@ -0,0 +1,5 @@ + o Minor features (pluggable transports): + - When launching managed pluggable transports on linux systems, + attempt to have the kernel deliver a SIGTERM on tor exit if + the pluggable transport process is still running. Resolves + ticket 15471. diff --git a/src/common/util.c b/src/common/util.c index 2c3a1a1019..246a0d3940 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -95,6 +95,9 @@ #ifdef HAVE_SYS_WAIT_H #include #endif +#if defined(HAVE_SYS_PRCTL_H) && defined(__linux__) +#include +#endif #ifdef __clang_analyzer__ #undef MALLOC_ZERO_WORKS @@ -4180,6 +4183,15 @@ tor_spawn_background(const char *const filename, const char **argv, if (0 == pid) { /* In child */ +#if defined(HAVE_SYS_PRCTL_H) && defined(__linux__) + /* Attempt to have the kernel issue a SIGTERM if the parent + * goes away. Certain attributes of the binary being execve()ed + * will clear this during the execve() call, but it's better + * than nothing. + */ + prctl(PR_SET_PDEATHSIG, SIGTERM); +#endif + child_state = CHILD_STATE_DUPOUT; /* Link child stdout to the write end of the pipe */ @@ -4225,8 +4237,10 @@ tor_spawn_background(const char *const filename, const char **argv, does not modify the arguments */ if (env) execve(filename, (char *const *) argv, env->unixoid_environment_block); - else - execvp(filename, (char *const *) argv); + else { + static char *new_env[] = { NULL }; + execve(filename, (char *const *) argv, new_env); + } /* If we got here, the exec or open(/dev/null) failed */