OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <errno.h> | 5 #include <errno.h> |
6 #include <fcntl.h> | 6 #include <fcntl.h> |
7 #include <linux/unistd.h> | 7 #include <linux/unistd.h> |
8 #include <netinet/in.h> | 8 #include <netinet/in.h> |
9 #include <netinet/tcp.h> | 9 #include <netinet/tcp.h> |
10 #include <netinet/udp.h> | 10 #include <netinet/udp.h> |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 | 130 |
131 ptr = strrchr(ptr, '\000'); | 131 ptr = strrchr(ptr, '\000'); |
132 strncat(ptr, msg1, sizeof(buf) - (ptr - buf)); | 132 strncat(ptr, msg1, sizeof(buf) - (ptr - buf)); |
133 | 133 |
134 ptr = strrchr(ptr, '\000'); | 134 ptr = strrchr(ptr, '\000'); |
135 if (HANDLE_EINTR(write(2, buf, ptr - buf))) { } | 135 if (HANDLE_EINTR(write(2, buf, ptr - buf))) { } |
136 | 136 |
137 return -ERR; | 137 return -ERR; |
138 } | 138 } |
139 | 139 |
140 static ErrorCode evaluator(int sysno) { | 140 static ErrorCode evaluator(int sysno, void *) { |
141 switch (sysno) { | 141 switch (sysno) { |
142 #if defined(__NR_accept) | 142 #if defined(__NR_accept) |
143 case __NR_accept: case __NR_accept4: | 143 case __NR_accept: case __NR_accept4: |
144 #endif | 144 #endif |
145 case __NR_alarm: | 145 case __NR_alarm: |
146 case __NR_brk: | 146 case __NR_brk: |
147 case __NR_clock_gettime: | 147 case __NR_clock_gettime: |
148 case __NR_close: | 148 case __NR_close: |
149 case __NR_dup: case __NR_dup2: | 149 case __NR_dup: case __NR_dup2: |
150 case __NR_epoll_create: case __NR_epoll_ctl: case __NR_epoll_wait: | 150 case __NR_epoll_create: case __NR_epoll_ctl: case __NR_epoll_wait: |
151 case __NR_exit: case __NR_exit_group: | 151 case __NR_exit: case __NR_exit_group: |
152 case __NR_fcntl: | 152 case __NR_fcntl: |
153 #if defined(__NR_fcntl64) | 153 #if defined(__NR_fcntl64) |
154 case __NR_fcntl64: | 154 case __NR_fcntl64: |
155 #endif | 155 #endif |
156 case __NR_fdatasync: | 156 case __NR_fdatasync: |
157 case __NR_fstat: | 157 case __NR_fstat: |
158 #if defined(__NR_fstat64) | 158 #if defined(__NR_fstat64) |
159 case __NR_fstat64: | 159 case __NR_fstat64: |
160 #endif | 160 #endif |
161 case __NR_ftruncate: | 161 case __NR_ftruncate: |
162 case __NR_futex: | 162 case __NR_futex: |
163 case __NR_getdents: case __NR_getdents64: | 163 case __NR_getdents: case __NR_getdents64: |
164 case __NR_getegid: | 164 case __NR_getegid: |
165 #if defined(__NR_getegid32) | 165 #if defined(__NR_getegid32) |
166 case __NR_getegid32: | 166 case __NR_getegid32: |
167 #endif | 167 #endif |
168 case __NR_geteuid: | 168 case __NR_geteuid: |
169 #if defined(__NR_geteuid32) | 169 #if defined(__NR_geteuid32) |
170 case __NR_geteuid32: | 170 case __NR_geteuid32: |
171 #endif | 171 #endif |
172 case __NR_getgid: | 172 case __NR_getgid: |
173 #if defined(__NR_getgid32) | 173 #if defined(__NR_getgid32) |
174 case __NR_getgid32: | 174 case __NR_getgid32: |
175 #endif | 175 #endif |
176 case __NR_getitimer: case __NR_setitimer: | 176 case __NR_getitimer: case __NR_setitimer: |
177 #if defined(__NR_getpeername) | 177 #if defined(__NR_getpeername) |
178 case __NR_getpeername: | 178 case __NR_getpeername: |
179 #endif | 179 #endif |
180 case __NR_getpid: case __NR_gettid: | 180 case __NR_getpid: case __NR_gettid: |
181 #if defined(__NR_getsockname) | 181 #if defined(__NR_getsockname) |
182 case __NR_getsockname: | 182 case __NR_getsockname: |
183 #endif | 183 #endif |
184 case __NR_gettimeofday: | 184 case __NR_gettimeofday: |
185 case __NR_getuid: | 185 case __NR_getuid: |
186 #if defined(__NR_getuid32) | 186 #if defined(__NR_getuid32) |
187 case __NR_getuid32: | 187 case __NR_getuid32: |
188 #endif | 188 #endif |
189 #if defined(__NR__llseek) | 189 #if defined(__NR__llseek) |
190 case __NR__llseek: | 190 case __NR__llseek: |
191 #endif | 191 #endif |
192 case __NR_lseek: | 192 case __NR_lseek: |
193 case __NR_nanosleep: | 193 case __NR_nanosleep: |
194 case __NR_pipe: case __NR_pipe2: | 194 case __NR_pipe: case __NR_pipe2: |
195 case __NR_poll: | 195 case __NR_poll: |
196 case __NR_pread64: case __NR_preadv: | 196 case __NR_pread64: case __NR_preadv: |
197 case __NR_pwrite64: case __NR_pwritev: | 197 case __NR_pwrite64: case __NR_pwritev: |
198 case __NR_read: case __NR_readv: | 198 case __NR_read: case __NR_readv: |
199 case __NR_restart_syscall: | 199 case __NR_restart_syscall: |
200 case __NR_set_robust_list: | 200 case __NR_set_robust_list: |
201 case __NR_rt_sigaction: | 201 case __NR_rt_sigaction: |
202 #if defined(__NR_sigaction) | 202 #if defined(__NR_sigaction) |
203 case __NR_sigaction: | 203 case __NR_sigaction: |
204 #endif | 204 #endif |
205 #if defined(__NR_signal) | 205 #if defined(__NR_signal) |
206 case __NR_signal: | 206 case __NR_signal: |
207 #endif | 207 #endif |
208 case __NR_rt_sigprocmask: | 208 case __NR_rt_sigprocmask: |
209 #if defined(__NR_sigprocmask) | 209 #if defined(__NR_sigprocmask) |
210 case __NR_sigprocmask: | 210 case __NR_sigprocmask: |
211 #endif | 211 #endif |
212 #if defined(__NR_shutdown) | 212 #if defined(__NR_shutdown) |
213 case __NR_shutdown: | 213 case __NR_shutdown: |
214 #endif | 214 #endif |
215 case __NR_rt_sigreturn: | 215 case __NR_rt_sigreturn: |
216 #if defined(__NR_sigreturn) | 216 #if defined(__NR_sigreturn) |
217 case __NR_sigreturn: | 217 case __NR_sigreturn: |
218 #endif | 218 #endif |
219 #if defined(__NR_socketpair) | 219 #if defined(__NR_socketpair) |
220 case __NR_socketpair: | 220 case __NR_socketpair: |
221 #endif | 221 #endif |
222 case __NR_time: | 222 case __NR_time: |
223 case __NR_uname: | 223 case __NR_uname: |
224 case __NR_write: case __NR_writev: | 224 case __NR_write: case __NR_writev: |
225 return ErrorCode(ErrorCode::ERR_ALLOWED); | 225 return ErrorCode(ErrorCode::ERR_ALLOWED); |
| 226 |
| 227 case __NR_prctl: |
| 228 // Allow PR_SET_DUMPABLE and PR_GET_DUMPABLE. Do not allow anything else. |
| 229 return Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
| 230 PR_SET_DUMPABLE, |
| 231 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 232 Sandbox::Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, |
| 233 PR_GET_DUMPABLE, |
| 234 ErrorCode(ErrorCode::ERR_ALLOWED), |
| 235 Sandbox::Trap(defaultHandler, NULL))); |
226 | 236 |
227 // The following system calls are temporarily permitted. This must be | 237 // The following system calls are temporarily permitted. This must be |
228 // tightened later. But we currently don't implement enough of the sandboxing | 238 // tightened later. But we currently don't implement enough of the sandboxing |
229 // API to do so. | 239 // API to do so. |
230 // As is, this sandbox isn't exactly safe :-/ | 240 // As is, this sandbox isn't exactly safe :-/ |
231 #if defined(__NR_sendmsg) | 241 #if defined(__NR_sendmsg) |
232 case __NR_sendmsg: case __NR_sendto: | 242 case __NR_sendmsg: case __NR_sendto: |
233 case __NR_recvmsg: case __NR_recvfrom: | 243 case __NR_recvmsg: case __NR_recvfrom: |
234 case __NR_getsockopt: case __NR_setsockopt: | 244 case __NR_getsockopt: case __NR_setsockopt: |
235 #elif defined(__NR_socketcall) | 245 #elif defined(__NR_socketcall) |
236 case __NR_socketcall: | 246 case __NR_socketcall: |
237 #endif | 247 #endif |
238 #if defined(__NR_shmat) | 248 #if defined(__NR_shmat) |
239 case __NR_shmat: case __NR_shmctl: case __NR_shmdt: case __NR_shmget: | 249 case __NR_shmat: case __NR_shmctl: case __NR_shmdt: case __NR_shmget: |
240 #elif defined(__NR_ipc) | 250 #elif defined(__NR_ipc) |
241 case __NR_ipc: | 251 case __NR_ipc: |
242 #endif | 252 #endif |
243 #if defined(__NR_mmap2) | 253 #if defined(__NR_mmap2) |
244 case __NR_mmap2: | 254 case __NR_mmap2: |
245 #else | 255 #else |
246 case __NR_mmap: | 256 case __NR_mmap: |
247 #endif | 257 #endif |
248 #if defined(__NR_ugetrlimit) | 258 #if defined(__NR_ugetrlimit) |
249 case __NR_ugetrlimit: | 259 case __NR_ugetrlimit: |
250 #endif | 260 #endif |
251 case __NR_getrlimit: | 261 case __NR_getrlimit: |
252 case __NR_ioctl: | 262 case __NR_ioctl: |
253 case __NR_prctl: | |
254 case __NR_clone: | 263 case __NR_clone: |
255 case __NR_munmap: case __NR_mprotect: case __NR_madvise: | 264 case __NR_munmap: case __NR_mprotect: case __NR_madvise: |
256 case __NR_remap_file_pages: | 265 case __NR_remap_file_pages: |
257 return ErrorCode(ErrorCode::ERR_ALLOWED); | 266 return ErrorCode(ErrorCode::ERR_ALLOWED); |
258 | 267 |
259 // Everything that isn't explicitly allowed is denied. | 268 // Everything that isn't explicitly allowed is denied. |
260 default: | 269 default: |
261 return Sandbox::Trap(defaultHandler, NULL); | 270 return Sandbox::Trap(defaultHandler, NULL); |
262 } | 271 } |
263 } | 272 } |
264 | 273 |
265 static void *threadFnc(void *arg) { | 274 static void *threadFnc(void *arg) { |
266 return arg; | 275 return arg; |
267 } | 276 } |
268 | 277 |
269 static void *sendmsgStressThreadFnc(void *arg) { | 278 static void *sendmsgStressThreadFnc(void *arg) { |
270 if (arg) { } | 279 if (arg) { } |
271 static const int repetitions = 100; | 280 static const int repetitions = 100; |
272 static const int kNumFds = 3; | 281 static const int kNumFds = 3; |
273 for (int rep = 0; rep < repetitions; ++rep) { | 282 for (int rep = 0; rep < repetitions; ++rep) { |
274 int fds[2 + kNumFds]; | 283 int fds[2 + kNumFds]; |
275 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) { | 284 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) { |
276 perror("socketpair()"); | 285 perror("socketpair()"); |
277 _exit(1); | 286 _exit(1); |
278 } | 287 } |
279 size_t len = 4; | 288 size_t len = 4; |
280 char buf[4]; | 289 char buf[4]; |
281 if (!Util::sendFds(fds[0], "test", 4, fds[1], fds[1], fds[1], -1) || | 290 if (!Util::SendFds(fds[0], "test", 4, fds[1], fds[1], fds[1], -1) || |
282 !Util::getFds(fds[1], buf, &len, fds+2, fds+3, fds+4, NULL) || | 291 !Util::GetFds(fds[1], buf, &len, fds+2, fds+3, fds+4, NULL) || |
283 len != 4 || | 292 len != 4 || |
284 memcmp(buf, "test", len) || | 293 memcmp(buf, "test", len) || |
285 write(fds[2], "demo", 4) != 4 || | 294 write(fds[2], "demo", 4) != 4 || |
286 read(fds[0], buf, 4) != 4 || | 295 read(fds[0], buf, 4) != 4 || |
287 memcmp(buf, "demo", 4)) { | 296 memcmp(buf, "demo", 4)) { |
288 perror("sending/receiving of fds"); | 297 perror("sending/receiving of fds"); |
289 _exit(1); | 298 _exit(1); |
290 } | 299 } |
291 for (int i = 0; i < 2+kNumFds; ++i) { | 300 for (int i = 0; i < 2+kNumFds; ++i) { |
292 if (close(fds[i])) { | 301 if (close(fds[i])) { |
293 perror("close"); | 302 perror("close"); |
294 _exit(1); | 303 _exit(1); |
295 } | 304 } |
296 } | 305 } |
297 } | 306 } |
298 return NULL; | 307 return NULL; |
299 } | 308 } |
300 | 309 |
301 int main(int argc, char *argv[]) { | 310 int main(int argc, char *argv[]) { |
302 if (argc) { } | 311 if (argc) { } |
303 if (argv) { } | 312 if (argv) { } |
304 int proc_fd = open("/proc", O_RDONLY|O_DIRECTORY); | 313 int proc_fd = open("/proc", O_RDONLY|O_DIRECTORY); |
305 if (Sandbox::supportsSeccompSandbox(proc_fd) != | 314 if (Sandbox::SupportsSeccompSandbox(proc_fd) != |
306 Sandbox::STATUS_AVAILABLE) { | 315 Sandbox::STATUS_AVAILABLE) { |
307 perror("sandbox"); | 316 perror("sandbox"); |
308 _exit(1); | 317 _exit(1); |
309 } | 318 } |
310 Sandbox::setProcFd(proc_fd); | 319 Sandbox::SetProcFd(proc_fd); |
311 Sandbox::setSandboxPolicy(evaluator, NULL); | 320 Sandbox::SetSandboxPolicy(evaluator, NULL); |
312 Sandbox::startSandbox(); | 321 Sandbox::StartSandbox(); |
313 | 322 |
314 // Check that we can create threads | 323 // Check that we can create threads |
315 pthread_t thr; | 324 pthread_t thr; |
316 if (!pthread_create(&thr, NULL, threadFnc, | 325 if (!pthread_create(&thr, NULL, threadFnc, |
317 reinterpret_cast<void *>(0x1234))) { | 326 reinterpret_cast<void *>(0x1234))) { |
318 void *ret; | 327 void *ret; |
319 pthread_join(thr, &ret); | 328 pthread_join(thr, &ret); |
320 if (ret != reinterpret_cast<void *>(0x1234)) { | 329 if (ret != reinterpret_cast<void *>(0x1234)) { |
321 perror("clone() failed"); | 330 perror("clone() failed"); |
322 _exit(1); | 331 _exit(1); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 } | 369 } |
361 | 370 |
362 // Check that we can send and receive file handles. | 371 // Check that we can send and receive file handles. |
363 int fds[3]; | 372 int fds[3]; |
364 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) { | 373 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) { |
365 perror("socketpair()"); | 374 perror("socketpair()"); |
366 _exit(1); | 375 _exit(1); |
367 } | 376 } |
368 size_t len = 4; | 377 size_t len = 4; |
369 char buf[4]; | 378 char buf[4]; |
370 if (!Util::sendFds(fds[0], "test", 4, fds[1], -1) || | 379 if (!Util::SendFds(fds[0], "test", 4, fds[1], -1) || |
371 !Util::getFds(fds[1], buf, &len, fds+2, NULL) || | 380 !Util::GetFds(fds[1], buf, &len, fds+2, NULL) || |
372 len != 4 || | 381 len != 4 || |
373 memcmp(buf, "test", len) || | 382 memcmp(buf, "test", len) || |
374 write(fds[2], "demo", 4) != 4 || | 383 write(fds[2], "demo", 4) != 4 || |
375 read(fds[0], buf, 4) != 4 || | 384 read(fds[0], buf, 4) != 4 || |
376 memcmp(buf, "demo", 4) || | 385 memcmp(buf, "demo", 4) || |
377 close(fds[0]) || | 386 close(fds[0]) || |
378 close(fds[1]) || | 387 close(fds[1]) || |
379 close(fds[2])) { | 388 close(fds[2])) { |
380 perror("sending/receiving of fds"); | 389 perror("sending/receiving of fds"); |
381 _exit(1); | 390 _exit(1); |
(...skipping 23 matching lines...) Expand all Loading... |
405 perror("pthread_create"); | 414 perror("pthread_create"); |
406 _exit(1); | 415 _exit(1); |
407 } | 416 } |
408 } | 417 } |
409 for (int i = 0; i < kSendmsgStressNumThreads; ++i) { | 418 for (int i = 0; i < kSendmsgStressNumThreads; ++i) { |
410 pthread_join(sendmsgStressThreads[i], NULL); | 419 pthread_join(sendmsgStressThreads[i], NULL); |
411 } | 420 } |
412 | 421 |
413 return 0; | 422 return 0; |
414 } | 423 } |
OLD | NEW |