summaryrefslogtreecommitdiffstats
path: root/crypto/openssh/sandbox-systrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/sandbox-systrace.c')
-rw-r--r--crypto/openssh/sandbox-systrace.c56
1 files changed, 28 insertions, 28 deletions
diff --git a/crypto/openssh/sandbox-systrace.c b/crypto/openssh/sandbox-systrace.c
index 5a39f4f..2d16a62 100644
--- a/crypto/openssh/sandbox-systrace.c
+++ b/crypto/openssh/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
OpenPOWER on IntegriCloud