- 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@
This commit is contained in:
Damien Miller 2011-08-06 06:16:23 +10:00
parent 6ea5e44871
commit 35e48198a8
2 changed files with 49 additions and 34 deletions

View File

@ -8,6 +8,11 @@
bzero the agent address. the kernel was for a while very cranky about bzero the agent address. the kernel was for a while very cranky about
these things. evne though that's fixed, always good to initialize these things. evne though that's fixed, always good to initialize
memory. ok deraadt djm 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 20110624
- (djm) [configure.ac Makefile.in sandbox-darwin.c] Add a sandbox for - (djm) [configure.ac Makefile.in sandbox-darwin.c] Add a sandbox for

View File

@ -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> * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
* *
@ -41,22 +41,30 @@
#include "ssh-sandbox.h" #include "ssh-sandbox.h"
#include "xmalloc.h" #include "xmalloc.h"
static const int preauth_policy[] = { struct sandbox_policy {
SYS___sysctl, int syscall;
SYS_close, int action;
SYS_exit, };
SYS_getpid,
SYS_gettimeofday, /* Permitted syscalls in preauth. Unlisted syscalls get SYSTR_POLICY_KILL */
SYS_madvise, static const struct sandbox_policy preauth_policy[] = {
SYS_mmap, { SYS_open, SYSTR_POLICY_NEVER },
SYS_mprotect,
SYS_poll, { SYS___sysctl, SYSTR_POLICY_PERMIT },
SYS_munmap, { SYS_close, SYSTR_POLICY_PERMIT },
SYS_read, { SYS_exit, SYSTR_POLICY_PERMIT },
SYS_select, { SYS_getpid, SYSTR_POLICY_PERMIT },
SYS_sigprocmask, { SYS_gettimeofday, SYSTR_POLICY_PERMIT },
SYS_write, { SYS_madvise, SYSTR_POLICY_PERMIT },
-1 { 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 { struct ssh_sandbox {
@ -64,7 +72,6 @@ struct ssh_sandbox {
int parent_sock; int parent_sock;
int systrace_fd; int systrace_fd;
pid_t child_pid; pid_t child_pid;
struct systrace_policy policy;
}; };
struct ssh_sandbox * struct ssh_sandbox *
@ -104,10 +111,11 @@ ssh_sandbox_child(struct ssh_sandbox *box)
static void static void
ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid, 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; int dev_systrace, i, j, found;
char whatever = 0; char whatever = 0;
struct systrace_policy policy;
debug3("%s: wait for child %ld", __func__, (long)child_pid); debug3("%s: wait for child %ld", __func__, (long)child_pid);
box->child_pid = 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)); box->systrace_fd, child_pid, strerror(errno));
/* Allocate and assign policy */ /* Allocate and assign policy */
bzero(&box->policy, sizeof(box->policy)); bzero(&policy, sizeof(policy));
box->policy.strp_op = SYSTR_POLICY_NEW; policy.strp_op = SYSTR_POLICY_NEW;
box->policy.strp_maxents = SYS_MAXSYSCALL; policy.strp_maxents = SYS_MAXSYSCALL;
if (ioctl(box->systrace_fd, STRIOCPOLICY, &box->policy) == -1) if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1)
fatal("%s: ioctl(%d, STRIOCPOLICY (new)): %s", __func__, fatal("%s: ioctl(%d, STRIOCPOLICY (new)): %s", __func__,
box->systrace_fd, strerror(errno)); box->systrace_fd, strerror(errno));
box->policy.strp_op = SYSTR_POLICY_ASSIGN; policy.strp_op = SYSTR_POLICY_ASSIGN;
box->policy.strp_pid = box->child_pid; policy.strp_pid = box->child_pid;
if (ioctl(box->systrace_fd, STRIOCPOLICY, &box->policy) == -1) if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1)
fatal("%s: ioctl(%d, STRIOCPOLICY (assign)): %s", fatal("%s: ioctl(%d, STRIOCPOLICY (assign)): %s",
__func__, box->systrace_fd, strerror(errno)); __func__, box->systrace_fd, strerror(errno));
/* Set per-syscall policy */ /* Set per-syscall policy */
for (i = 0; i < SYS_MAXSYSCALL; i++) { for (i = 0; i < SYS_MAXSYSCALL; i++) {
for (j = found = 0; allowed_syscalls[j] != -1 && !found; j++) { found = 0;
if (allowed_syscalls[j] == i) for (j = 0; allowed_syscalls[j].syscall != -1; j++) {
if (allowed_syscalls[j].syscall == i) {
found = 1; found = 1;
break;
}
} }
box->policy.strp_op = SYSTR_POLICY_MODIFY; policy.strp_op = SYSTR_POLICY_MODIFY;
box->policy.strp_code = i; policy.strp_code = i;
box->policy.strp_policy = found ? policy.strp_policy = found ?
SYSTR_POLICY_PERMIT : SYSTR_POLICY_KILL; allowed_syscalls[j].action : SYSTR_POLICY_KILL;
if (found) if (found)
debug3("%s: policy: enable syscall %d", __func__, i); debug3("%s: policy: enable syscall %d", __func__, i);
if (ioctl(box->systrace_fd, STRIOCPOLICY, if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1)
&box->policy) == -1)
fatal("%s: ioctl(%d, STRIOCPOLICY (modify)): %s", fatal("%s: ioctl(%d, STRIOCPOLICY (modify)): %s",
__func__, box->systrace_fd, strerror(errno)); __func__, box->systrace_fd, strerror(errno));
} }