From e87d1a63bdef0ae08f2d94d67fd8daa8fbb63fb4 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Mon, 18 Mar 2013 11:13:53 -0400 Subject: [PATCH] killUser: Don't let the child kill itself on Apple The kill(2) in Apple's libc follows POSIX semantics, which means that kill(-1, SIGKILL) will kill the calling process too. Since nix has no way to distinguish between the process successfully killing everything and the process being killed by a rogue builder in that case, it can't safely conclude that killUser was successful. Luckily, the actual kill syscall takes a parameter that determines whether POSIX semantics are followed, so we can call that syscall directly and avoid the issue on Apple. Signed-off-by: Shea Levy --- src/libutil/util.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/libutil/util.cc b/src/libutil/util.cc index dad5f624bd..bc07a84f4d 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -12,6 +12,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + #include "util.hh" @@ -851,7 +855,16 @@ void killUser(uid_t uid) throw SysError("setting uid"); while (true) { +#ifdef __APPLE__ + /* OSX's kill syscall takes a third parameter that, among other + things, determines if kill(-1, signo) affects the calling + process. In the OSX libc, it's set to true, which means + "follow POSIX", which we don't want here + */ + if (syscall(SYS_kill, -1, SIGKILL, false) == 0) break; +#else if (kill(-1, SIGKILL) == 0) break; +#endif if (errno == ESRCH) break; /* no more processes */ if (errno != EINTR) throw SysError(format("cannot kill processes for uid `%1%'") % uid);