diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | sandbox-systrace.c | 78 |
2 files changed, 49 insertions, 34 deletions
@@ -8,6 +8,11 @@ | |||
8 | bzero the agent address. the kernel was for a while very cranky about | 8 | bzero the agent address. the kernel was for a while very cranky about |
9 | these things. evne though that's fixed, always good to initialize | 9 | these things. evne though that's fixed, always good to initialize |
10 | memory. ok deraadt djm | 10 | memory. ok deraadt djm |
11 | - djm@cvs.openbsd.org 2011/07/29 14:42:45 | ||
12 | [sandbox-systrace.c] | ||
13 | fail open(2) with EPERM rather than SIGKILLing the whole process. libc | ||
14 | will call open() to do strerror() when NLS is enabled; | ||
15 | feedback and ok markus@ | ||
11 | 16 | ||
12 | 20110624 | 17 | 20110624 |
13 | - (djm) [configure.ac Makefile.in sandbox-darwin.c] Add a sandbox for | 18 | - (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 @@ | |||
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 | ||
44 | static const int preauth_policy[] = { | 44 | struct 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, | 50 | static 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 | ||
62 | struct ssh_sandbox { | 70 | struct 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 | ||
70 | struct ssh_sandbox * | 77 | struct ssh_sandbox * |
@@ -104,10 +111,11 @@ ssh_sandbox_child(struct ssh_sandbox *box) | |||
104 | 111 | ||
105 | static void | 112 | static void |
106 | ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid, | 113 | ssh_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 | } |