summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2011-08-06 06:16:23 +1000
committerDamien Miller <djm@mindrot.org>2011-08-06 06:16:23 +1000
commit35e48198a80aba7361bce8dde4fba464800e3ff6 (patch)
tree9065e576f662ac04a9d60d1411c3349ce20d73e1
parent6ea5e44871314a980e7506282450b58fc78ae9aa (diff)
- djm@cvs.openbsd.org 2011/07/29 14:42:45
[sandbox-systrace.c] fail open(2) with EPERM rather than SIGKILLing the whole process. libc will call open() to do strerror() when NLS is enabled; feedback and ok markus@
-rw-r--r--ChangeLog5
-rw-r--r--sandbox-systrace.c78
2 files changed, 49 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index 7de7fdbf..ccca485f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,11 @@
bzero the agent address. the kernel was for a while very cranky about
these things. evne though that's fixed, always good to initialize
memory. ok deraadt djm
+ - djm@cvs.openbsd.org 2011/07/29 14:42:45
+ [sandbox-systrace.c]
+ fail open(2) with EPERM rather than SIGKILLing the whole process. libc
+ will call open() to do strerror() when NLS is enabled;
+ feedback and ok markus@
20110624
- (djm) [configure.ac Makefile.in sandbox-darwin.c] Add a sandbox for
diff --git a/sandbox-systrace.c b/sandbox-systrace.c
index 8058b7d4..5a39f4fe 100644
--- a/sandbox-systrace.c
+++ b/sandbox-systrace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sandbox-systrace.c,v 1.3 2011/06/23 09:34:13 djm Exp $ */
+/* $OpenBSD: sandbox-systrace.c,v 1.4 2011/07/29 14:42:45 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
@@ -41,22 +41,30 @@
#include "ssh-sandbox.h"
#include "xmalloc.h"
-static const int preauth_policy[] = {
- SYS___sysctl,
- SYS_close,
- SYS_exit,
- SYS_getpid,
- SYS_gettimeofday,
- SYS_madvise,
- SYS_mmap,
- SYS_mprotect,
- SYS_poll,
- SYS_munmap,
- SYS_read,
- SYS_select,
- SYS_sigprocmask,
- SYS_write,
- -1
+struct sandbox_policy {
+ int syscall;
+ int action;
+};
+
+/* Permitted syscalls in preauth. Unlisted syscalls get SYSTR_POLICY_KILL */
+static const struct sandbox_policy preauth_policy[] = {
+ { SYS_open, SYSTR_POLICY_NEVER },
+
+ { SYS___sysctl, SYSTR_POLICY_PERMIT },
+ { SYS_close, SYSTR_POLICY_PERMIT },
+ { SYS_exit, SYSTR_POLICY_PERMIT },
+ { SYS_getpid, SYSTR_POLICY_PERMIT },
+ { SYS_gettimeofday, SYSTR_POLICY_PERMIT },
+ { SYS_madvise, SYSTR_POLICY_PERMIT },
+ { SYS_mmap, SYSTR_POLICY_PERMIT },
+ { SYS_mprotect, SYSTR_POLICY_PERMIT },
+ { SYS_poll, SYSTR_POLICY_PERMIT },
+ { SYS_munmap, SYSTR_POLICY_PERMIT },
+ { SYS_read, SYSTR_POLICY_PERMIT },
+ { SYS_select, SYSTR_POLICY_PERMIT },
+ { SYS_sigprocmask, SYSTR_POLICY_PERMIT },
+ { SYS_write, SYSTR_POLICY_PERMIT },
+ { -1, -1 }
};
struct ssh_sandbox {
@@ -64,7 +72,6 @@ struct ssh_sandbox {
int parent_sock;
int systrace_fd;
pid_t child_pid;
- struct systrace_policy policy;
};
struct ssh_sandbox *
@@ -104,10 +111,11 @@ ssh_sandbox_child(struct ssh_sandbox *box)
static void
ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,
- const int *allowed_syscalls)
+ const struct sandbox_policy *allowed_syscalls)
{
int dev_systrace, i, j, found;
char whatever = 0;
+ struct systrace_policy policy;
debug3("%s: wait for child %ld", __func__, (long)child_pid);
box->child_pid = child_pid;
@@ -131,33 +139,35 @@ ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,
box->systrace_fd, child_pid, strerror(errno));
/* Allocate and assign policy */
- bzero(&box->policy, sizeof(box->policy));
- box->policy.strp_op = SYSTR_POLICY_NEW;
- box->policy.strp_maxents = SYS_MAXSYSCALL;
- if (ioctl(box->systrace_fd, STRIOCPOLICY, &box->policy) == -1)
+ bzero(&policy, sizeof(policy));
+ policy.strp_op = SYSTR_POLICY_NEW;
+ policy.strp_maxents = SYS_MAXSYSCALL;
+ if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1)
fatal("%s: ioctl(%d, STRIOCPOLICY (new)): %s", __func__,
box->systrace_fd, strerror(errno));
- box->policy.strp_op = SYSTR_POLICY_ASSIGN;
- box->policy.strp_pid = box->child_pid;
- if (ioctl(box->systrace_fd, STRIOCPOLICY, &box->policy) == -1)
+ policy.strp_op = SYSTR_POLICY_ASSIGN;
+ policy.strp_pid = box->child_pid;
+ if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1)
fatal("%s: ioctl(%d, STRIOCPOLICY (assign)): %s",
__func__, box->systrace_fd, strerror(errno));
/* Set per-syscall policy */
for (i = 0; i < SYS_MAXSYSCALL; i++) {
- for (j = found = 0; allowed_syscalls[j] != -1 && !found; j++) {
- if (allowed_syscalls[j] == i)
+ found = 0;
+ for (j = 0; allowed_syscalls[j].syscall != -1; j++) {
+ if (allowed_syscalls[j].syscall == i) {
found = 1;
+ break;
+ }
}
- box->policy.strp_op = SYSTR_POLICY_MODIFY;
- box->policy.strp_code = i;
- box->policy.strp_policy = found ?
- SYSTR_POLICY_PERMIT : SYSTR_POLICY_KILL;
+ policy.strp_op = SYSTR_POLICY_MODIFY;
+ policy.strp_code = i;
+ policy.strp_policy = found ?
+ allowed_syscalls[j].action : SYSTR_POLICY_KILL;
if (found)
debug3("%s: policy: enable syscall %d", __func__, i);
- if (ioctl(box->systrace_fd, STRIOCPOLICY,
- &box->policy) == -1)
+ if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1)
fatal("%s: ioctl(%d, STRIOCPOLICY (modify)): %s",
__func__, box->systrace_fd, strerror(errno));
}