| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 1 #include "library.h" | 5 #include "library.h" |
| 2 #include "sandbox_impl.h" | 6 #include "sandbox_impl.h" |
| 3 #include "syscall_table.h" | 7 #include "syscall_table.h" |
| 4 | 8 |
| 5 namespace playground { | 9 namespace playground { |
| 6 | 10 |
| 7 // Global variables | 11 // Global variables |
| 8 int Sandbox::proc_self_maps_ = -1; | 12 int Sandbox::proc_self_maps_ = -1; |
| 9 enum Sandbox::SandboxStatus Sandbox::status_ = STATUS_UNKNOWN; | 13 enum Sandbox::SandboxStatus Sandbox::status_ = STATUS_UNKNOWN; |
| 10 int Sandbox::pid_; | 14 int Sandbox::pid_; |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 return 0; | 369 return 0; |
| 366 } | 370 } |
| 367 pid_t pid; | 371 pid_t pid; |
| 368 switch ((pid = sys.fork())) { | 372 switch ((pid = sys.fork())) { |
| 369 case -1: | 373 case -1: |
| 370 status_ = STATUS_UNSUPPORTED; | 374 status_ = STATUS_UNSUPPORTED; |
| 371 return 0; | 375 return 0; |
| 372 case 0: { | 376 case 0: { |
| 373 int devnull = sys.open("/dev/null", O_RDWR, 0); | 377 int devnull = sys.open("/dev/null", O_RDWR, 0); |
| 374 if (devnull >= 0) { | 378 if (devnull >= 0) { |
| 375 dup2(devnull, 0); | 379 sys.dup2(devnull, 0); |
| 376 dup2(devnull, 1); | 380 sys.dup2(devnull, 1); |
| 377 dup2(devnull, 2); | 381 sys.dup2(devnull, 2); |
| 382 sys.close(devnull); |
| 378 } | 383 } |
| 379 if (proc_fd >= 0) { | 384 if (proc_fd >= 0) { |
| 380 setProcSelfMaps(sys.openat(proc_fd, "self/maps", O_RDONLY, 0)); | 385 setProcSelfMaps(sys.openat(proc_fd, "self/maps", O_RDONLY, 0)); |
| 381 } | 386 } |
| 382 startSandbox(); | 387 startSandbox(); |
| 383 write(sys, fds[1], "", 1); | 388 write(sys, fds[1], "", 1); |
| 384 | 389 |
| 385 // Try to tell the trusted thread to shut down the entire process in an | 390 // Try to tell the trusted thread to shut down the entire process in an |
| 386 // orderly fashion | 391 // orderly fashion |
| 387 defaultSystemCallHandler(__NR_exit_group, 0, 0, 0, 0, 0, 0); | 392 defaultSystemCallHandler(__NR_exit_group, 0, 0, 0, 0, 0, 0); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 416 | 421 |
| 417 void Sandbox::startSandbox() { | 422 void Sandbox::startSandbox() { |
| 418 if (status_ == STATUS_UNSUPPORTED) { | 423 if (status_ == STATUS_UNSUPPORTED) { |
| 419 die("The seccomp sandbox is not supported on this computer"); | 424 die("The seccomp sandbox is not supported on this computer"); |
| 420 } else if (status_ == STATUS_ENABLED) { | 425 } else if (status_ == STATUS_ENABLED) { |
| 421 return; | 426 return; |
| 422 } | 427 } |
| 423 | 428 |
| 424 SysCalls sys; | 429 SysCalls sys; |
| 425 if (proc_self_maps_ < 0) { | 430 if (proc_self_maps_ < 0) { |
| 426 proc_self_maps_ = sys.open("/proc/self/maps", O_RDONLY, 0); | 431 proc_self_maps_ = sys.open("/proc/self/maps", O_RDONLY, 0); |
| 427 if (proc_self_maps_ < 0) { | 432 if (proc_self_maps_ < 0) { |
| 428 die("Cannot access \"/proc/self/maps\""); | 433 die("Cannot access \"/proc/self/maps\""); |
| 429 } | 434 } |
| 430 } | 435 } |
| 431 | 436 |
| 432 // The pid is unchanged for the entire program, so we can retrieve it once | 437 // The pid is unchanged for the entire program, so we can retrieve it once |
| 433 // and store it in a global variable. | 438 // and store it in a global variable. |
| 434 pid_ = sys.getpid(); | 439 pid_ = sys.getpid(); |
| 435 | 440 |
| 436 // Block all signals, except for the RDTSC handler | 441 // Block all signals, except for the RDTSC handler |
| 437 setupSignalHandlers(); | 442 setupSignalHandlers(); |
| 438 | 443 |
| 439 // Get socketpairs for talking to the trusted process | 444 // Get socketpairs for talking to the trusted process |
| 440 int pair[4]; | 445 int pair[4]; |
| 441 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) || | 446 if (sys.socketpair(AF_UNIX, SOCK_STREAM, 0, pair) || |
| 442 socketpair(AF_UNIX, SOCK_STREAM, 0, pair+2)) { | 447 sys.socketpair(AF_UNIX, SOCK_STREAM, 0, pair+2)) { |
| 443 die("Failed to create trusted thread"); | 448 die("Failed to create trusted thread"); |
| 444 } | 449 } |
| 445 processFdPub_ = pair[0]; | 450 processFdPub_ = pair[0]; |
| 446 cloneFdPub_ = pair[2]; | 451 cloneFdPub_ = pair[2]; |
| 447 SecureMemArgs::Args* secureMem = createTrustedProcess(pair[0], pair[1], | 452 SecureMemArgs* secureMem = createTrustedProcess(pair[0], pair[1], |
| 448 pair[2], pair[3]); | 453 pair[2], pair[3]); |
| 449 | 454 |
| 450 // We find all libraries that have system calls and redirect the system | 455 // We find all libraries that have system calls and redirect the system |
| 451 // calls to the sandbox. If we miss any system calls, the application will be | 456 // calls to the sandbox. If we miss any system calls, the application will be |
| 452 // terminated by the kernel's seccomp code. So, from a security point of | 457 // terminated by the kernel's seccomp code. So, from a security point of |
| 453 // view, if this code fails to identify system calls, we are still behaving | 458 // view, if this code fails to identify system calls, we are still behaving |
| 454 // correctly. | 459 // correctly. |
| 455 { | 460 { |
| 456 Maps maps(proc_self_maps_); | 461 Maps maps(proc_self_maps_); |
| 457 const char *libs[] = { "ld", "libc", "librt", "libpthread", NULL }; | 462 const char *libs[] = { "ld", "libc", "librt", "libpthread", NULL }; |
| 458 | 463 |
| 459 // Intercept system calls in the VDSO segment (if any). This has to happen | 464 // Intercept system calls in the VDSO segment (if any). This has to happen |
| 460 // before intercepting system calls in any of the other libraries, as | 465 // before intercepting system calls in any of the other libraries, as |
| 461 // the main kernel entry point might be inside of the VDSO and we need to | 466 // the main kernel entry point might be inside of the VDSO and we need to |
| 462 // determine its address before we can compare it to jumps from inside | 467 // determine its address before we can compare it to jumps from inside |
| 463 // other libraries. | 468 // other libraries. |
| 464 for (Maps::const_iterator iter = maps.begin(); iter != maps.end(); ++iter){ | 469 for (Maps::const_iterator iter = maps.begin(); iter != maps.end(); ++iter){ |
| 465 Library* library = *iter; | 470 Library* library = *iter; |
| 466 if (library->isVDSO() && library->parseElf()) { | 471 if (library->isVDSO() && library->parseElf()) { |
| 467 library->makeWritable(true); | 472 library->makeWritable(true); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 // Creating the trusted thread enables sandboxing | 520 // Creating the trusted thread enables sandboxing |
| 516 createTrustedThread(processFdPub_, cloneFdPub_, secureMem); | 521 createTrustedThread(processFdPub_, cloneFdPub_, secureMem); |
| 517 | 522 |
| 518 // We can no longer check for sandboxing support at this point, but we also | 523 // We can no longer check for sandboxing support at this point, but we also |
| 519 // know for a fact that it is available (as we just turned it on). So update | 524 // know for a fact that it is available (as we just turned it on). So update |
| 520 // the status to reflect this information. | 525 // the status to reflect this information. |
| 521 status_ = STATUS_ENABLED; | 526 status_ = STATUS_ENABLED; |
| 522 } | 527 } |
| 523 | 528 |
| 524 } // namespace | 529 } // namespace |
| OLD | NEW |