summaryrefslogtreecommitdiff
path: root/sandbox-systrace.c
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 /sandbox-systrace.c
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@
Diffstat (limited to 'sandbox-systrace.c')
-rw-r--r--sandbox-systrace.c78
1 files changed, 44 insertions, 34 deletions
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 @@
1/* $OpenBSD: sandbox-systrace.c,v 1.3 2011/06/23 09:34:13 djm Exp $ */ 1/* $OpenBSD: sandbox-systrace.c,v 1.4 2011/07/29 14:42:45 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2011 Damien Miller <djm@mindrot.org>
4 * 4 *
@@ -41,22 +41,30 @@
41#include "ssh-sandbox.h" 41#include "ssh-sandbox.h"
42#include "xmalloc.h" 42#include "xmalloc.h"
43 43
44static const int preauth_policy[] = { 44struct sandbox_policy {
45 SYS___sysctl, 45 int syscall;
46 SYS_close, 46 int action;
47 SYS_exit, 47};
48 SYS_getpid, 48
49 SYS_gettimeofday, 49/* Permitted syscalls in preauth. Unlisted syscalls get SYSTR_POLICY_KILL */
50 SYS_madvise, 50static const struct sandbox_policy preauth_policy[] = {
51 SYS_mmap, 51 { SYS_open, SYSTR_POLICY_NEVER },
52 SYS_mprotect, 52
53 SYS_poll, 53 { SYS___sysctl, SYSTR_POLICY_PERMIT },
54 SYS_munmap, 54 { SYS_close, SYSTR_POLICY_PERMIT },
55 SYS_read, 55 { SYS_exit, SYSTR_POLICY_PERMIT },
56 SYS_select, 56 { SYS_getpid, SYSTR_POLICY_PERMIT },
57 SYS_sigprocmask, 57 { SYS_gettimeofday, SYSTR_POLICY_PERMIT },
58 SYS_write, 58 { SYS_madvise, SYSTR_POLICY_PERMIT },
59 -1 59 { SYS_mmap, SYSTR_POLICY_PERMIT },
60 { SYS_mprotect, SYSTR_POLICY_PERMIT },
61 { SYS_poll, SYSTR_POLICY_PERMIT },
62 { SYS_munmap, SYSTR_POLICY_PERMIT },
63 { SYS_read, SYSTR_POLICY_PERMIT },
64 { SYS_select, SYSTR_POLICY_PERMIT },
65 { SYS_sigprocmask, SYSTR_POLICY_PERMIT },
66 { SYS_write, SYSTR_POLICY_PERMIT },
67 { -1, -1 }
60}; 68};
61 69
62struct ssh_sandbox { 70struct ssh_sandbox {
@@ -64,7 +72,6 @@ struct ssh_sandbox {
64 int parent_sock; 72 int parent_sock;
65 int systrace_fd; 73 int systrace_fd;
66 pid_t child_pid; 74 pid_t child_pid;
67 struct systrace_policy policy;
68}; 75};
69 76
70struct ssh_sandbox * 77struct ssh_sandbox *
@@ -104,10 +111,11 @@ ssh_sandbox_child(struct ssh_sandbox *box)
104 111
105static void 112static void
106ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid, 113ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,
107 const int *allowed_syscalls) 114 const struct sandbox_policy *allowed_syscalls)
108{ 115{
109 int dev_systrace, i, j, found; 116 int dev_systrace, i, j, found;
110 char whatever = 0; 117 char whatever = 0;
118 struct systrace_policy policy;
111 119
112 debug3("%s: wait for child %ld", __func__, (long)child_pid); 120 debug3("%s: wait for child %ld", __func__, (long)child_pid);
113 box->child_pid = child_pid; 121 box->child_pid = child_pid;
@@ -131,33 +139,35 @@ ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid,
131 box->systrace_fd, child_pid, strerror(errno)); 139 box->systrace_fd, child_pid, strerror(errno));
132 140
133 /* Allocate and assign policy */ 141 /* Allocate and assign policy */
134 bzero(&box->policy, sizeof(box->policy)); 142 bzero(&policy, sizeof(policy));
135 box->policy.strp_op = SYSTR_POLICY_NEW; 143 policy.strp_op = SYSTR_POLICY_NEW;
136 box->policy.strp_maxents = SYS_MAXSYSCALL; 144 policy.strp_maxents = SYS_MAXSYSCALL;
137 if (ioctl(box->systrace_fd, STRIOCPOLICY, &box->policy) == -1) 145 if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1)
138 fatal("%s: ioctl(%d, STRIOCPOLICY (new)): %s", __func__, 146 fatal("%s: ioctl(%d, STRIOCPOLICY (new)): %s", __func__,
139 box->systrace_fd, strerror(errno)); 147 box->systrace_fd, strerror(errno));
140 148
141 box->policy.strp_op = SYSTR_POLICY_ASSIGN; 149 policy.strp_op = SYSTR_POLICY_ASSIGN;
142 box->policy.strp_pid = box->child_pid; 150 policy.strp_pid = box->child_pid;
143 if (ioctl(box->systrace_fd, STRIOCPOLICY, &box->policy) == -1) 151 if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1)
144 fatal("%s: ioctl(%d, STRIOCPOLICY (assign)): %s", 152 fatal("%s: ioctl(%d, STRIOCPOLICY (assign)): %s",
145 __func__, box->systrace_fd, strerror(errno)); 153 __func__, box->systrace_fd, strerror(errno));
146 154
147 /* Set per-syscall policy */ 155 /* Set per-syscall policy */
148 for (i = 0; i < SYS_MAXSYSCALL; i++) { 156 for (i = 0; i < SYS_MAXSYSCALL; i++) {
149 for (j = found = 0; allowed_syscalls[j] != -1 && !found; j++) { 157 found = 0;
150 if (allowed_syscalls[j] == i) 158 for (j = 0; allowed_syscalls[j].syscall != -1; j++) {
159 if (allowed_syscalls[j].syscall == i) {
151 found = 1; 160 found = 1;
161 break;
162 }
152 } 163 }
153 box->policy.strp_op = SYSTR_POLICY_MODIFY; 164 policy.strp_op = SYSTR_POLICY_MODIFY;
154 box->policy.strp_code = i; 165 policy.strp_code = i;
155 box->policy.strp_policy = found ? 166 policy.strp_policy = found ?
156 SYSTR_POLICY_PERMIT : SYSTR_POLICY_KILL; 167 allowed_syscalls[j].action : SYSTR_POLICY_KILL;
157 if (found) 168 if (found)
158 debug3("%s: policy: enable syscall %d", __func__, i); 169 debug3("%s: policy: enable syscall %d", __func__, i);
159 if (ioctl(box->systrace_fd, STRIOCPOLICY, 170 if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1)
160 &box->policy) == -1)
161 fatal("%s: ioctl(%d, STRIOCPOLICY (modify)): %s", 171 fatal("%s: ioctl(%d, STRIOCPOLICY (modify)): %s",
162 __func__, box->systrace_fd, strerror(errno)); 172 __func__, box->systrace_fd, strerror(errno));
163 } 173 }