Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(444)

Side by Side Diff: content/zygote/zygote_main_linux.cc

Issue 915823002: Namespace sandbox: add important security checks (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/content_common.gypi ('k') | sandbox/linux/services/credentials.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/zygote/zygote_main.h" 5 #include "content/zygote/zygote_main.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <pthread.h> 9 #include <pthread.h>
10 #include <signal.h> 10 #include <signal.h>
(...skipping 13 matching lines...) Expand all
24 #include "base/pickle.h" 24 #include "base/pickle.h"
25 #include "base/posix/eintr_wrapper.h" 25 #include "base/posix/eintr_wrapper.h"
26 #include "base/posix/unix_domain_socket_linux.h" 26 #include "base/posix/unix_domain_socket_linux.h"
27 #include "base/rand_util.h" 27 #include "base/rand_util.h"
28 #include "base/strings/safe_sprintf.h" 28 #include "base/strings/safe_sprintf.h"
29 #include "base/strings/string_number_conversions.h" 29 #include "base/strings/string_number_conversions.h"
30 #include "base/sys_info.h" 30 #include "base/sys_info.h"
31 #include "build/build_config.h" 31 #include "build/build_config.h"
32 #include "content/common/child_process_sandbox_support_impl_linux.h" 32 #include "content/common/child_process_sandbox_support_impl_linux.h"
33 #include "content/common/font_config_ipc_linux.h" 33 #include "content/common/font_config_ipc_linux.h"
34 #include "content/common/sandbox_linux/sandbox_debug_handling_linux.h"
34 #include "content/common/sandbox_linux/sandbox_linux.h" 35 #include "content/common/sandbox_linux/sandbox_linux.h"
35 #include "content/common/zygote_commands_linux.h" 36 #include "content/common/zygote_commands_linux.h"
36 #include "content/public/common/content_switches.h" 37 #include "content/public/common/content_switches.h"
37 #include "content/public/common/main_function_params.h" 38 #include "content/public/common/main_function_params.h"
38 #include "content/public/common/sandbox_linux.h" 39 #include "content/public/common/sandbox_linux.h"
39 #include "content/public/common/zygote_fork_delegate_linux.h" 40 #include "content/public/common/zygote_fork_delegate_linux.h"
40 #include "content/zygote/zygote_linux.h" 41 #include "content/zygote/zygote_linux.h"
41 #include "crypto/nss_util.h" 42 #include "crypto/nss_util.h"
42 #include "sandbox/linux/services/credentials.h"
43 #include "sandbox/linux/services/init_process_reaper.h" 43 #include "sandbox/linux/services/init_process_reaper.h"
44 #include "sandbox/linux/services/libc_urandom_override.h" 44 #include "sandbox/linux/services/libc_urandom_override.h"
45 #include "sandbox/linux/services/namespace_sandbox.h" 45 #include "sandbox/linux/services/namespace_sandbox.h"
46 #include "sandbox/linux/suid/client/setuid_sandbox_client.h" 46 #include "sandbox/linux/suid/client/setuid_sandbox_client.h"
47 #include "third_party/icu/source/i18n/unicode/timezone.h" 47 #include "third_party/icu/source/i18n/unicode/timezone.h"
48 #include "third_party/skia/include/ports/SkFontConfigInterface.h" 48 #include "third_party/skia/include/ports/SkFontConfigInterface.h"
49 49
50 #if defined(OS_LINUX) 50 #if defined(OS_LINUX)
51 #include <sys/prctl.h> 51 #include <sys/prctl.h>
52 #endif 52 #endif
(...skipping 12 matching lines...) Expand all
65 #endif 65 #endif
66 66
67 #if defined(ADDRESS_SANITIZER) 67 #if defined(ADDRESS_SANITIZER)
68 #include <sanitizer/asan_interface.h> 68 #include <sanitizer/asan_interface.h>
69 #endif 69 #endif
70 70
71 namespace content { 71 namespace content {
72 72
73 namespace { 73 namespace {
74 74
75 void DoChrootSignalHandler(int) {
76 const int old_errno = errno;
77 const char kFirstMessage[] = "Chroot signal handler called.\n";
78 ignore_result(write(STDERR_FILENO, kFirstMessage, sizeof(kFirstMessage) - 1));
79
80 const int chroot_ret = chroot("/");
81
82 char kSecondMessage[100];
83 const ssize_t printed =
84 base::strings::SafeSPrintf(kSecondMessage,
85 "chroot() returned %d. Errno is %d.\n",
86 chroot_ret,
87 errno);
88 if (printed > 0 && printed < static_cast<ssize_t>(sizeof(kSecondMessage))) {
89 ignore_result(write(STDERR_FILENO, kSecondMessage, printed));
90 }
91 errno = old_errno;
92 }
93
94 // This is a quick hack to allow testing sandbox crash reports in production
95 // binaries.
96 // This installs a signal handler for SIGUSR2 that performs a chroot().
97 // In most of our BPF policies, it is a "watched" system call which will
98 // trigger a SIGSYS signal whose handler will crash.
99 // This has been added during the investigation of https://crbug.com/415842.
100 void InstallSandboxCrashTestHandler() {
101 struct sigaction act = {};
102 act.sa_handler = DoChrootSignalHandler;
103 CHECK_EQ(0, sigemptyset(&act.sa_mask));
104 act.sa_flags = 0;
105
106 PCHECK(0 == sigaction(SIGUSR2, &act, NULL));
107 }
108
109 void CloseFds(const std::vector<int>& fds) { 75 void CloseFds(const std::vector<int>& fds) {
110 for (const auto& it : fds) { 76 for (const auto& it : fds) {
111 PCHECK(0 == IGNORE_EINTR(close(it))); 77 PCHECK(0 == IGNORE_EINTR(close(it)));
112 } 78 }
113 } 79 }
114 80
115 } // namespace 81 } // namespace
116 82
117 // See http://code.google.com/p/chromium/wiki/LinuxZygote 83 // See http://code.google.com/p/chromium/wiki/LinuxZygote
118 84
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 // newly created process. 360 // newly created process.
395 const bool init_created = 361 const bool init_created =
396 sandbox::CreateInitProcessReaper(post_fork_parent_callback); 362 sandbox::CreateInitProcessReaper(post_fork_parent_callback);
397 if (!init_created) { 363 if (!init_created) {
398 LOG(ERROR) << "Error creating an init process to reap zombies"; 364 LOG(ERROR) << "Error creating an init process to reap zombies";
399 return false; 365 return false;
400 } 366 }
401 return true; 367 return true;
402 } 368 }
403 369
404 static bool MaybeSetProcessNonDumpable() {
405 const base::CommandLine& command_line =
406 *base::CommandLine::ForCurrentProcess();
407 if (command_line.HasSwitch(switches::kAllowSandboxDebugging)) {
408 // If sandbox debugging is allowed, install a handler for sandbox-related
409 // crash testing.
410 InstallSandboxCrashTestHandler();
411 return true;
412 }
413
414 if (prctl(PR_SET_DUMPABLE, 0) != 0) {
415 PLOG(ERROR) << "Failed to set non-dumpable flag";
416 return false;
417 }
418
419 return prctl(PR_GET_DUMPABLE) == 0;
420 }
421
422 // Enter the setuid sandbox. This requires the current process to have been 370 // Enter the setuid sandbox. This requires the current process to have been
423 // created through the setuid sandbox. 371 // created through the setuid sandbox.
424 static bool EnterSuidSandbox(sandbox::SetuidSandboxClient* setuid_sandbox, 372 static bool EnterSuidSandbox(sandbox::SetuidSandboxClient* setuid_sandbox,
425 base::Closure* post_fork_parent_callback) { 373 base::Closure* post_fork_parent_callback) {
426 DCHECK(setuid_sandbox); 374 DCHECK(setuid_sandbox);
427 DCHECK(setuid_sandbox->IsSuidSandboxChild()); 375 DCHECK(setuid_sandbox->IsSuidSandboxChild());
428 376
429 // Use the SUID sandbox. This still allows the seccomp sandbox to 377 // Use the SUID sandbox. This still allows the seccomp sandbox to
430 // be enabled by the process later. 378 // be enabled by the process later.
431 379
(...skipping 14 matching lines...) Expand all
446 "is not the init process. Please, make sure the SUID " 394 "is not the init process. Please, make sure the SUID "
447 "binary is up to date."; 395 "binary is up to date.";
448 } 396 }
449 397
450 if (getpid() == 1) { 398 if (getpid() == 1) {
451 // The setuid sandbox has created a new PID namespace and we need 399 // The setuid sandbox has created a new PID namespace and we need
452 // to assume the role of init. 400 // to assume the role of init.
453 CHECK(CreateInitProcessReaper(post_fork_parent_callback)); 401 CHECK(CreateInitProcessReaper(post_fork_parent_callback));
454 } 402 }
455 403
456 CHECK(MaybeSetProcessNonDumpable()); 404 CHECK(SandboxDebugHandling::SetDumpableStatusAndHandlers());
457 return true; 405 return true;
458 } 406 }
459 407
460 static void EnterNamespaceSandbox(base::Closure* post_fork_parent_callback) { 408 static void EnterNamespaceSandbox(LinuxSandbox* linux_sandbox,
461 pid_t pid = getpid(); 409 base::Closure* post_fork_parent_callback) {
462 if (sandbox::NamespaceSandbox::InNewPidNamespace()) { 410 linux_sandbox->EngageNamespaceSandbox();
463 CHECK_EQ(1, pid);
464 }
465 411
466 CHECK(sandbox::Credentials::MoveToNewUserNS()); 412 if (getpid() == 1) {
467 CHECK(sandbox::Credentials::DropFileSystemAccess());
468 CHECK(sandbox::Credentials::DropAllCapabilities());
469
470 // This needs to happen after moving to a new user NS, since doing so involves
471 // writing the UID/GID map.
472 CHECK(MaybeSetProcessNonDumpable());
473
474 if (pid == 1) {
475 CHECK(CreateInitProcessReaper(post_fork_parent_callback)); 413 CHECK(CreateInitProcessReaper(post_fork_parent_callback));
476 } 414 }
477 } 415 }
478 416
479 #if defined(ADDRESS_SANITIZER) 417 #if defined(ADDRESS_SANITIZER)
480 const size_t kSanitizerMaxMessageLength = 1 * 1024 * 1024; 418 const size_t kSanitizerMaxMessageLength = 1 * 1024 * 1024;
481 419
482 // A helper process which collects code coverage data from the renderers over a 420 // A helper process which collects code coverage data from the renderers over a
483 // socket and dumps it to a file. See http://crbug.com/336212 for discussion. 421 // socket and dumps it to a file. See http://crbug.com/336212 for discussion.
484 static void SanitizerCoverageHelper(int socket_fd, int file_fd) { 422 static void SanitizerCoverageHelper(int socket_fd, int file_fd) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 #if !defined(THREAD_SANITIZER) 481 #if !defined(THREAD_SANITIZER)
544 DCHECK(linux_sandbox->IsSingleThreaded()); 482 DCHECK(linux_sandbox->IsSingleThreaded());
545 #endif 483 #endif
546 484
547 sandbox::SetuidSandboxClient* setuid_sandbox = 485 sandbox::SetuidSandboxClient* setuid_sandbox =
548 linux_sandbox->setuid_sandbox_client(); 486 linux_sandbox->setuid_sandbox_client();
549 if (setuid_sandbox->IsSuidSandboxChild()) { 487 if (setuid_sandbox->IsSuidSandboxChild()) {
550 CHECK(EnterSuidSandbox(setuid_sandbox, post_fork_parent_callback)) 488 CHECK(EnterSuidSandbox(setuid_sandbox, post_fork_parent_callback))
551 << "Failed to enter setuid sandbox"; 489 << "Failed to enter setuid sandbox";
552 } else if (sandbox::NamespaceSandbox::InNewUserNamespace()) { 490 } else if (sandbox::NamespaceSandbox::InNewUserNamespace()) {
553 EnterNamespaceSandbox(post_fork_parent_callback); 491 EnterNamespaceSandbox(linux_sandbox, post_fork_parent_callback);
554 } else { 492 } else {
555 CHECK(!using_layer1_sandbox); 493 CHECK(!using_layer1_sandbox);
556 } 494 }
557 } 495 }
558 496
559 bool ZygoteMain(const MainFunctionParams& params, 497 bool ZygoteMain(const MainFunctionParams& params,
560 ScopedVector<ZygoteForkDelegate> fork_delegates) { 498 ScopedVector<ZygoteForkDelegate> fork_delegates) {
561 g_am_zygote_or_renderer = true; 499 g_am_zygote_or_renderer = true;
562 sandbox::InitLibcUrandomOverrides(); 500 sandbox::InitLibcUrandomOverrides();
563 501
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 const bool namespace_sandbox_engaged = sandbox_flags & kSandboxLinuxUserNS; 592 const bool namespace_sandbox_engaged = sandbox_flags & kSandboxLinuxUserNS;
655 CHECK_EQ(using_namespace_sandbox, namespace_sandbox_engaged); 593 CHECK_EQ(using_namespace_sandbox, namespace_sandbox_engaged);
656 594
657 Zygote zygote(sandbox_flags, fork_delegates.Pass(), extra_children, 595 Zygote zygote(sandbox_flags, fork_delegates.Pass(), extra_children,
658 extra_fds); 596 extra_fds);
659 // This function call can return multiple times, once per fork(). 597 // This function call can return multiple times, once per fork().
660 return zygote.ProcessRequests(); 598 return zygote.ProcessRequests();
661 } 599 }
662 600
663 } // namespace content 601 } // namespace content
OLDNEW
« no previous file with comments | « content/content_common.gypi ('k') | sandbox/linux/services/credentials.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698