diff options
Diffstat (limited to 'sandbox-systrace.c')
| -rw-r--r-- | sandbox-systrace.c | 56 | 
1 files changed, 28 insertions, 28 deletions
| diff --git a/sandbox-systrace.c b/sandbox-systrace.c index 5a39f4fe146f8..2d16a627fe379 100644 --- a/sandbox-systrace.c +++ b/sandbox-systrace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sandbox-systrace.c,v 1.4 2011/07/29 14:42:45 djm Exp $ */ +/* $OpenBSD: sandbox-systrace.c,v 1.6 2012/06/30 14:35:09 markus Exp $ */  /*   * Copyright (c) 2011 Damien Miller <djm@mindrot.org>   * @@ -24,12 +24,14 @@  #include <sys/ioctl.h>  #include <sys/syscall.h>  #include <sys/socket.h> +#include <sys/wait.h>  #include <dev/systrace.h>  #include <errno.h>  #include <fcntl.h>  #include <limits.h> +#include <signal.h>  #include <stdarg.h>  #include <stdio.h>  #include <stdlib.h> @@ -58,6 +60,7 @@ static const struct sandbox_policy preauth_policy[] = {  	{ SYS_madvise, SYSTR_POLICY_PERMIT },  	{ SYS_mmap, SYSTR_POLICY_PERMIT },  	{ SYS_mprotect, SYSTR_POLICY_PERMIT }, +	{ SYS_mquery, SYSTR_POLICY_PERMIT },  	{ SYS_poll, SYSTR_POLICY_PERMIT },  	{ SYS_munmap, SYSTR_POLICY_PERMIT },  	{ SYS_read, SYSTR_POLICY_PERMIT }, @@ -68,26 +71,21 @@ static const struct sandbox_policy preauth_policy[] = {  };  struct ssh_sandbox { -	int child_sock; -	int parent_sock;  	int systrace_fd;  	pid_t child_pid; +	void (*osigchld)(int);  };  struct ssh_sandbox *  ssh_sandbox_init(void)  {  	struct ssh_sandbox *box; -	int s[2];  	debug3("%s: preparing systrace sandbox", __func__);  	box = xcalloc(1, sizeof(*box)); -	if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == -1) -		fatal("%s: socketpair: %s", __func__, strerror(errno)); -	box->child_sock = s[0]; -	box->parent_sock = s[1];  	box->systrace_fd = -1;  	box->child_pid = 0; +	box->osigchld = signal(SIGCHLD, SIG_IGN);  	return box;  } @@ -95,35 +93,38 @@ ssh_sandbox_init(void)  void  ssh_sandbox_child(struct ssh_sandbox *box)  { -	char whatever = 0; - -	close(box->parent_sock); -	/* Signal parent that we are ready */  	debug3("%s: ready", __func__); -	if (atomicio(vwrite, box->child_sock, &whatever, 1) != 1) -		fatal("%s: write: %s", __func__, strerror(errno)); -	/* Wait for parent to signal for us to go */ -	if (atomicio(read, box->child_sock, &whatever, 1) != 1) -		fatal("%s: read: %s", __func__, strerror(errno)); +	signal(SIGCHLD, box->osigchld); +	if (kill(getpid(), SIGSTOP) != 0) +		fatal("%s: kill(%d, SIGSTOP)", __func__, getpid());  	debug3("%s: started", __func__); -	close(box->child_sock);  }  static void  ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,      const struct sandbox_policy *allowed_syscalls)  { -	int dev_systrace, i, j, found; -	char whatever = 0; +	int dev_systrace, i, j, found, status; +	pid_t pid;  	struct systrace_policy policy; +	/* Wait for the child to send itself a SIGSTOP */  	debug3("%s: wait for child %ld", __func__, (long)child_pid); +	do { +		pid = waitpid(child_pid, &status, WUNTRACED); +	} while (pid == -1 && errno == EINTR); +	signal(SIGCHLD, box->osigchld); +	if (!WIFSTOPPED(status)) { +		if (WIFSIGNALED(status)) +			fatal("%s: child terminated with signal %d", +			    __func__, WTERMSIG(status)); +		if (WIFEXITED(status)) +			fatal("%s: child exited with status %d", +			    __func__, WEXITSTATUS(status)); +		fatal("%s: child not stopped", __func__); +	} +	debug3("%s: child %ld stopped", __func__, (long)child_pid);  	box->child_pid = child_pid; -	close(box->child_sock); -	/* Wait for child to signal that it is ready */ -	if (atomicio(read, box->parent_sock, &whatever, 1) != 1) -		fatal("%s: read: %s", __func__, strerror(errno)); -	debug3("%s: child %ld ready", __func__, (long)child_pid);  	/* Set up systracing of child */  	if ((dev_systrace = open("/dev/systrace", O_RDONLY)) == -1) @@ -174,9 +175,8 @@ ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,  	/* Signal the child to start running */  	debug3("%s: start child %ld", __func__, (long)child_pid); -	if (atomicio(vwrite, box->parent_sock, &whatever, 1) != 1) -		fatal("%s: write: %s", __func__, strerror(errno)); -	close(box->parent_sock); +	if (kill(box->child_pid, SIGCONT) != 0) +		fatal("%s: kill(%d, SIGCONT)", __func__, box->child_pid);  }  void | 
