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 "content/public/common/sandbox_init.h" | 5 #include "content/public/common/sandbox_init.h" |
6 | 6 |
7 #if defined(OS_LINUX) && defined(__x86_64__) | 7 #if defined(OS_LINUX) && defined(__x86_64__) |
8 | 8 |
9 #include <asm/unistd.h> | 9 #include <asm/unistd.h> |
10 #include <errno.h> | 10 #include <errno.h> |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "content/public/common/content_switches.h" | 25 #include "content/public/common/content_switches.h" |
26 | 26 |
27 #ifndef PR_SET_NO_NEW_PRIVS | 27 #ifndef PR_SET_NO_NEW_PRIVS |
28 #define PR_SET_NO_NEW_PRIVS 38 | 28 #define PR_SET_NO_NEW_PRIVS 38 |
29 #endif | 29 #endif |
30 | 30 |
31 #ifndef SYS_SECCOMP | 31 #ifndef SYS_SECCOMP |
32 #define SYS_SECCOMP 1 | 32 #define SYS_SECCOMP 1 |
33 #endif | 33 #endif |
34 | 34 |
| 35 #ifndef __NR_migrate_pages |
| 36 #define __NR_migrate_pages 256 |
| 37 #endif |
| 38 |
35 #ifndef __NR_openat | 39 #ifndef __NR_openat |
36 #define __NR_openat 257 | 40 #define __NR_openat 257 |
37 #endif | 41 #endif |
38 | 42 |
39 #ifndef __NR_mkdirat | 43 #ifndef __NR_mkdirat |
40 #define __NR_mkdirat 258 | 44 #define __NR_mkdirat 258 |
41 #endif | 45 #endif |
42 | 46 |
43 #ifndef __NR_readlinkat | 47 #ifndef __NR_readlinkat |
44 #define __NR_readlinkat 267 | 48 #define __NR_readlinkat 267 |
45 #endif | 49 #endif |
46 | 50 |
| 51 #ifndef __NR_move_pages |
| 52 #define __NR_move_pages 279 |
| 53 #endif |
| 54 |
47 #ifndef __NR_eventfd2 | 55 #ifndef __NR_eventfd2 |
48 #define __NR_eventfd2 290 | 56 #define __NR_eventfd2 290 |
49 #endif | 57 #endif |
50 | 58 |
| 59 #ifndef __NR_process_vm_readv |
| 60 #define __NR_process_vm_readv 310 |
| 61 #endif |
| 62 |
| 63 #ifndef __NR_process_vm_writev |
| 64 #define __NR_process_vm_writev 311 |
| 65 #endif |
| 66 |
51 // Constants from very new header files that we can't yet include. | 67 // Constants from very new header files that we can't yet include. |
52 #ifndef SECCOMP_MODE_FILTER | 68 #ifndef SECCOMP_MODE_FILTER |
53 #define SECCOMP_MODE_FILTER 2 | 69 #define SECCOMP_MODE_FILTER 2 |
54 #define SECCOMP_RET_KILL 0x00000000U | 70 #define SECCOMP_RET_KILL 0x00000000U |
55 #define SECCOMP_RET_TRAP 0x00030000U | 71 #define SECCOMP_RET_TRAP 0x00030000U |
56 #define SECCOMP_RET_ERRNO 0x00050000U | 72 #define SECCOMP_RET_ERRNO 0x00050000U |
57 #define SECCOMP_RET_ALLOW 0x7fff0000U | 73 #define SECCOMP_RET_ALLOW 0x7fff0000U |
58 #endif | 74 #endif |
59 | 75 |
60 | 76 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 // "4" is magic offset for the arch number. | 174 // "4" is magic offset for the arch number. |
159 EmitLoad(4, program); | 175 EmitLoad(4, program); |
160 EmitJEQJT1(AUDIT_ARCH_X86_64, program); | 176 EmitJEQJT1(AUDIT_ARCH_X86_64, program); |
161 EmitRet(SECCOMP_RET_KILL, program); | 177 EmitRet(SECCOMP_RET_KILL, program); |
162 | 178 |
163 // Load the syscall number. | 179 // Load the syscall number. |
164 // "0" is magic offset for the syscall number. | 180 // "0" is magic offset for the syscall number. |
165 EmitLoad(0, program); | 181 EmitLoad(0, program); |
166 } | 182 } |
167 | 183 |
| 184 static void EmitTrap(std::vector<struct sock_filter>* program) { |
| 185 EmitRet(SECCOMP_RET_TRAP, program); |
| 186 } |
| 187 |
| 188 static void EmitAllow(std::vector<struct sock_filter>* program) { |
| 189 EmitRet(SECCOMP_RET_ALLOW, program); |
| 190 } |
| 191 |
168 static void EmitAllowSyscall(int nr, std::vector<struct sock_filter>* program) { | 192 static void EmitAllowSyscall(int nr, std::vector<struct sock_filter>* program) { |
169 EmitJEQJF(nr, 1, program); | 193 EmitJEQJF(nr, 1, program); |
170 EmitRet(SECCOMP_RET_ALLOW, program); | 194 EmitAllow(program); |
| 195 } |
| 196 |
| 197 static void EmitDenySyscall(int nr, std::vector<struct sock_filter>* program) { |
| 198 EmitJEQJF(nr, 1, program); |
| 199 EmitTrap(program); |
171 } | 200 } |
172 | 201 |
173 static void EmitAllowSyscallArgN(int nr, | 202 static void EmitAllowSyscallArgN(int nr, |
174 int arg_nr, | 203 int arg_nr, |
175 int arg_val, | 204 int arg_val, |
176 std::vector<struct sock_filter>* program) { | 205 std::vector<struct sock_filter>* program) { |
177 // Jump forward 4 on no-match so that we also skip the unneccessary reload of | 206 // Jump forward 4 on no-match so that we also skip the unneccessary reload of |
178 // syscall_nr. (It is unneccessary because we have not trashed it yet.) | 207 // syscall_nr. (It is unneccessary because we have not trashed it yet.) |
179 EmitJEQJF(nr, 4, program); | 208 EmitJEQJF(nr, 4, program); |
180 EmitLoadArg(arg_nr, program); | 209 EmitLoadArg(arg_nr, program); |
181 EmitJEQJF(arg_val, 1, program); | 210 EmitJEQJF(arg_val, 1, program); |
182 EmitRet(SECCOMP_RET_ALLOW, program); | 211 EmitAllow(program); |
183 // We trashed syscall_nr so put it back in the accumulator. | 212 // We trashed syscall_nr so put it back in the accumulator. |
184 EmitLoad(0, program); | 213 EmitLoad(0, program); |
185 } | 214 } |
186 | 215 |
187 static void EmitFailSyscall(int nr, int err, | 216 static void EmitFailSyscall(int nr, int err, |
188 std::vector<struct sock_filter>* program) { | 217 std::vector<struct sock_filter>* program) { |
189 EmitJEQJF(nr, 1, program); | 218 EmitJEQJF(nr, 1, program); |
190 EmitRet(SECCOMP_RET_ERRNO | err, program); | 219 EmitRet(SECCOMP_RET_ERRNO | err, program); |
191 } | 220 } |
192 | 221 |
193 static void EmitTrap(std::vector<struct sock_filter>* program) { | |
194 EmitRet(SECCOMP_RET_TRAP, program); | |
195 } | |
196 | |
197 // TODO(cevans) -- only really works as advertised once we restrict clone() | 222 // TODO(cevans) -- only really works as advertised once we restrict clone() |
198 // to CLONE_THREAD. | 223 // to CLONE_THREAD. |
199 static void EmitAllowSignalSelf(std::vector<struct sock_filter>* program) { | 224 static void EmitAllowSignalSelf(std::vector<struct sock_filter>* program) { |
200 EmitAllowSyscallArgN(__NR_kill, 1, getpid(), program); | 225 EmitAllowSyscallArgN(__NR_kill, 1, getpid(), program); |
201 EmitAllowSyscallArgN(__NR_tgkill, 1, getpid(), program); | 226 EmitAllowSyscallArgN(__NR_tgkill, 1, getpid(), program); |
202 } | 227 } |
203 | 228 |
204 static void EmitAllowGettime(std::vector<struct sock_filter>* program) { | 229 static void EmitAllowGettime(std::vector<struct sock_filter>* program) { |
205 EmitAllowSyscall(__NR_clock_gettime, program); | 230 EmitAllowSyscall(__NR_clock_gettime, program); |
206 EmitAllowSyscall(__NR_gettimeofday, program); | 231 EmitAllowSyscall(__NR_gettimeofday, program); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 EmitAllowSignalSelf(program); | 351 EmitAllowSignalSelf(program); |
327 | 352 |
328 // These are under investigation, and hopefully not here for the long term. | 353 // These are under investigation, and hopefully not here for the long term. |
329 EmitAllowSyscall(__NR_shmctl, program); | 354 EmitAllowSyscall(__NR_shmctl, program); |
330 EmitAllowSyscall(__NR_shmat, program); | 355 EmitAllowSyscall(__NR_shmat, program); |
331 EmitAllowSyscall(__NR_shmdt, program); | 356 EmitAllowSyscall(__NR_shmdt, program); |
332 | 357 |
333 EmitSetupEmptyFileSystem(program); | 358 EmitSetupEmptyFileSystem(program); |
334 } | 359 } |
335 | 360 |
| 361 static void ApplyNoPtracePolicy(std::vector<struct sock_filter>* program) { |
| 362 EmitDenySyscall(__NR_ptrace, program); |
| 363 EmitDenySyscall(__NR_process_vm_readv, program); |
| 364 EmitDenySyscall(__NR_process_vm_writev, program); |
| 365 EmitDenySyscall(__NR_migrate_pages, program); |
| 366 EmitDenySyscall(__NR_move_pages, program); |
| 367 } |
| 368 |
336 static bool CanUseSeccompFilters() { | 369 static bool CanUseSeccompFilters() { |
337 int ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, 0, 0, 0); | 370 int ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, 0, 0, 0); |
338 if (ret != 0 && errno == EFAULT) | 371 if (ret != 0 && errno == EFAULT) |
339 return true; | 372 return true; |
340 return false; | 373 return false; |
341 } | 374 } |
342 | 375 |
343 static void InstallFilter(const std::vector<struct sock_filter>& program) { | 376 static void InstallFilter(const std::vector<struct sock_filter>& program) { |
344 int ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | 377 int ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); |
345 PLOG_IF(FATAL, ret != 0) << "prctl(PR_SET_NO_NEW_PRIVS) failed"; | 378 PLOG_IF(FATAL, ret != 0) << "prctl(PR_SET_NO_NEW_PRIVS) failed"; |
(...skipping 25 matching lines...) Expand all Loading... |
371 if (!CanUseSeccompFilters()) | 404 if (!CanUseSeccompFilters()) |
372 return; | 405 return; |
373 | 406 |
374 CheckSingleThreaded(); | 407 CheckSingleThreaded(); |
375 | 408 |
376 std::vector<struct sock_filter> program; | 409 std::vector<struct sock_filter> program; |
377 EmitPreamble(&program); | 410 EmitPreamble(&program); |
378 | 411 |
379 if (process_type == switches::kGpuProcess) { | 412 if (process_type == switches::kGpuProcess) { |
380 ApplyGPUPolicy(&program); | 413 ApplyGPUPolicy(&program); |
| 414 EmitTrap(&program); // Default deny. |
381 } else if (process_type == switches::kPpapiPluginProcess) { | 415 } else if (process_type == switches::kPpapiPluginProcess) { |
382 ApplyFlashPolicy(&program); | 416 ApplyFlashPolicy(&program); |
| 417 EmitTrap(&program); // Default deny. |
| 418 } else if (process_type == switches::kRendererProcess || |
| 419 process_type == switches::kWorkerProcess) { |
| 420 ApplyNoPtracePolicy(&program); |
| 421 EmitAllow(&program); // Default permit. |
383 } else { | 422 } else { |
384 NOTREACHED(); | 423 NOTREACHED(); |
385 } | 424 } |
386 | 425 |
387 EmitTrap(&program); | |
388 | |
389 InstallSIGSYSHandler(); | 426 InstallSIGSYSHandler(); |
390 InstallFilter(program); | 427 InstallFilter(program); |
391 } | 428 } |
392 | 429 |
393 } // namespace content | 430 } // namespace content |
394 | 431 |
395 #else | 432 #else |
396 | 433 |
397 namespace content { | 434 namespace content { |
398 | 435 |
399 void InitializeSandbox() { | 436 void InitializeSandbox() { |
400 } | 437 } |
401 | 438 |
402 } // namespace content | 439 } // namespace content |
403 | 440 |
404 #endif | 441 #endif |
405 | 442 |
OLD | NEW |