summaryrefslogtreecommitdiff
path: root/src/common/util.c
diff options
context:
space:
mode:
authorYawning Angel <yawning@schwanenlied.me>2015-03-26 14:56:14 +0000
committerYawning Angel <yawning@schwanenlied.me>2015-03-26 14:56:14 +0000
commitfa81508eb2d9a2a2ea69c2c585735aef7aaff97c (patch)
tree44816667310992771957819d6801063ac4b9f9be /src/common/util.c
parent732322b710d515a55ebbaa984fa12f19ccb333e8 (diff)
downloadtor-fa81508eb2d9a2a2ea69c2c585735aef7aaff97c.tar.gz
tor-fa81508eb2d9a2a2ea69c2c585735aef7aaff97c.zip
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.
Diffstat (limited to 'src/common/util.c')
-rw-r--r--src/common/util.c18
1 files changed, 16 insertions, 2 deletions
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 <sys/wait.h>
#endif
+#if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
+#include <sys/prctl.h>
+#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 */