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 <shea@shealevy.com>
This commit is contained in:
Shea Levy 2013-03-18 11:13:53 -04:00 committed by Eelco Dolstra
parent 7cf539c728
commit e87d1a63bd
1 changed files with 13 additions and 0 deletions

View File

@ -12,6 +12,10 @@
#include <fcntl.h>
#include <limits.h>
#ifdef __APPLE__
#include <sys/syscall.h>
#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);