From 35e48198a80aba7361bce8dde4fba464800e3ff6 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sat, 6 Aug 2011 06:16:23 +1000 Subject: [PATCH] - 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@ --- ChangeLog | 5 +++ sandbox-systrace.c | 78 ++++++++++++++++++++++++++-------------------- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7de7fdbf8..ccca485f8 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 8058b7d40..5a39f4fe1 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 * @@ -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)); }