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:
		
							parent
							
								
									7cf539c728
								
							
						
					
					
						commit
						e87d1a63bd
					
				
					 1 changed files with 13 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue