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