| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 <dlfcn.h> | 5 #include <dlfcn.h> |
| 6 #include <fcntl.h> |
| 6 #include <sys/epoll.h> | 7 #include <sys/epoll.h> |
| 7 #include <sys/prctl.h> | 8 #include <sys/prctl.h> |
| 8 #include <sys/signal.h> | 9 #include <sys/signal.h> |
| 9 #include <sys/socket.h> | 10 #include <sys/socket.h> |
| 11 #include <sys/stat.h> |
| 10 #include <sys/types.h> | 12 #include <sys/types.h> |
| 11 #include <sys/wait.h> | 13 #include <sys/wait.h> |
| 12 #include <unistd.h> | 14 #include <unistd.h> |
| 13 | 15 |
| 14 #if defined(CHROMIUM_SELINUX) | 16 #if defined(CHROMIUM_SELINUX) |
| 15 #include <selinux/selinux.h> | 17 #include <selinux/selinux.h> |
| 16 #include <selinux/context.h> | 18 #include <selinux/context.h> |
| 17 #endif | 19 #endif |
| 18 | 20 |
| 19 #include "base/basictypes.h" | 21 #include "base/basictypes.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 43 #include "sandbox/linux/seccomp/sandbox.h" | 45 #include "sandbox/linux/seccomp/sandbox.h" |
| 44 | 46 |
| 45 #include "unicode/timezone.h" | 47 #include "unicode/timezone.h" |
| 46 | 48 |
| 47 // http://code.google.com/p/chromium/wiki/LinuxZygote | 49 // http://code.google.com/p/chromium/wiki/LinuxZygote |
| 48 | 50 |
| 49 static const int kBrowserDescriptor = 3; | 51 static const int kBrowserDescriptor = 3; |
| 50 static const int kMagicSandboxIPCDescriptor = 5; | 52 static const int kMagicSandboxIPCDescriptor = 5; |
| 51 static const int kZygoteIdDescriptor = 7; | 53 static const int kZygoteIdDescriptor = 7; |
| 52 static bool g_suid_sandbox_active = false; | 54 static bool g_suid_sandbox_active = false; |
| 55 static int g_proc_fd = -1; |
| 53 | 56 |
| 54 // This is the object which implements the zygote. The ZygoteMain function, | 57 // This is the object which implements the zygote. The ZygoteMain function, |
| 55 // which is called from ChromeMain, at the the bottom and simple constructs one | 58 // which is called from ChromeMain, at the the bottom and simple constructs one |
| 56 // of these objects and runs it. | 59 // of these objects and runs it. |
| 57 class Zygote { | 60 class Zygote { |
| 58 public: | 61 public: |
| 59 bool ProcessRequests() { | 62 bool ProcessRequests() { |
| 60 // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the | 63 // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the |
| 61 // browser on it. | 64 // browser on it. |
| 62 // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel. | 65 // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel. |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 if (dummy_fd < 0) | 230 if (dummy_fd < 0) |
| 228 goto error; | 231 goto error; |
| 229 | 232 |
| 230 if (!base::FileDescriptorGetInode(&dummy_inode, dummy_fd)) | 233 if (!base::FileDescriptorGetInode(&dummy_inode, dummy_fd)) |
| 231 goto error; | 234 goto error; |
| 232 } | 235 } |
| 233 | 236 |
| 234 child = fork(); | 237 child = fork(); |
| 235 | 238 |
| 236 if (!child) { | 239 if (!child) { |
| 240 // Try to open /proc/self/maps as the seccomp sandbox needs access to it |
| 241 if (g_proc_fd >= 0) { |
| 242 int proc_self_maps = openat(g_proc_fd, "self/maps", O_RDONLY); |
| 243 if (proc_self_maps >= 0) { |
| 244 SeccompSandboxSetProcSelfMaps(proc_self_maps); |
| 245 } |
| 246 close(g_proc_fd); |
| 247 g_proc_fd = -1; |
| 248 } |
| 249 |
| 237 close(kBrowserDescriptor); // our socket from the browser | 250 close(kBrowserDescriptor); // our socket from the browser |
| 238 close(kZygoteIdDescriptor); // another socket from the browser | 251 close(kZygoteIdDescriptor); // another socket from the browser |
| 239 Singleton<base::GlobalDescriptors>()->Reset(mapping); | 252 Singleton<base::GlobalDescriptors>()->Reset(mapping); |
| 240 | 253 |
| 241 // Reset the process-wide command line to our new command line. | 254 // Reset the process-wide command line to our new command line. |
| 242 CommandLine::Reset(); | 255 CommandLine::Reset(); |
| 243 CommandLine::Init(0, NULL); | 256 CommandLine::Init(0, NULL); |
| 244 CommandLine::ForCurrentProcess()->InitFromArgv(args); | 257 CommandLine::ForCurrentProcess()->InitFromArgv(args); |
| 245 CommandLine::SetProcTitle(); | 258 CommandLine::SetProcTitle(); |
| 246 return true; | 259 return true; |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 return true; | 589 return true; |
| 577 } | 590 } |
| 578 | 591 |
| 579 #endif // CHROMIUM_SELINUX | 592 #endif // CHROMIUM_SELINUX |
| 580 | 593 |
| 581 bool ZygoteMain(const MainFunctionParams& params) { | 594 bool ZygoteMain(const MainFunctionParams& params) { |
| 582 #if !defined(CHROMIUM_SELINUX) | 595 #if !defined(CHROMIUM_SELINUX) |
| 583 g_am_zygote_or_renderer = true; | 596 g_am_zygote_or_renderer = true; |
| 584 #endif | 597 #endif |
| 585 | 598 |
| 599 // The seccomp sandbox needs access to files in /proc, which might be denied |
| 600 // after one of the other sandboxes have been started. So, obtain a suitable |
| 601 // file handle in advance. |
| 586 if (CommandLine::ForCurrentProcess()->HasSwitch( | 602 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 587 switches::kEnableSeccompSandbox)) { | 603 switches::kEnableSeccompSandbox)) { |
| 588 if (!SupportsSeccompSandbox()) { | 604 g_proc_fd = open("/proc", O_DIRECTORY | O_RDONLY); |
| 605 if (g_proc_fd < 0) { |
| 606 LOG(ERROR) << "WARNING! Cannot access \"/proc\". Disabling seccomp " |
| 607 "sandboxing."; |
| 608 } |
| 609 } |
| 610 |
| 611 // Turn on the SELinux or SUID sandbox |
| 612 if (!EnterSandbox()) { |
| 613 LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: " |
| 614 << errno << ")"; |
| 615 return false; |
| 616 } |
| 617 |
| 618 // The seccomp sandbox will be turned on when the renderers start. But we can |
| 619 // already check if sufficient support is available so that we only need to |
| 620 // print one error message for the entire browser session. |
| 621 if (g_proc_fd >= 0 && |
| 622 CommandLine::ForCurrentProcess()->HasSwitch( |
| 623 switches::kEnableSeccompSandbox)) { |
| 624 if (!SupportsSeccompSandbox(g_proc_fd)) { |
| 589 // There are a good number of users who cannot use the seccomp sandbox | 625 // There are a good number of users who cannot use the seccomp sandbox |
| 590 // (e.g. because their distribution does not enable seccomp mode by | 626 // (e.g. because their distribution does not enable seccomp mode by |
| 591 // default). While we would prefer to deny execution in this case, it | 627 // default). While we would prefer to deny execution in this case, it |
| 592 // seems more realistic to continue in degraded mode. | 628 // seems more realistic to continue in degraded mode. |
| 593 LOG(ERROR) << "WARNING! This machine lacks support needed for the " | 629 LOG(ERROR) << "WARNING! This machine lacks support needed for the " |
| 594 "Seccomp sandbox. Running renderers with Seccomp " | 630 "Seccomp sandbox. Running renderers with Seccomp " |
| 595 "sandboxing disabled."; | 631 "sandboxing disabled."; |
| 596 } else { | 632 } else { |
| 597 LOG(INFO) << "Enabling experimental Seccomp sandbox."; | 633 LOG(INFO) << "Enabling experimental Seccomp sandbox."; |
| 598 } | 634 } |
| 599 } | 635 } |
| 600 | 636 |
| 601 if (!EnterSandbox()) { | |
| 602 LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: " | |
| 603 << errno << ")"; | |
| 604 return false; | |
| 605 } | |
| 606 | |
| 607 Zygote zygote; | 637 Zygote zygote; |
| 608 return zygote.ProcessRequests(); | 638 return zygote.ProcessRequests(); |
| 609 } | 639 } |
| OLD | NEW |