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

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

Issue 1041163003: Revert of Start all children in their own PID namespace. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 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/common/sandbox_linux/sandbox_linux.cc ('k') | content/zygote/zygote_main_linux.cc » ('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_linux.h" 5 #include "content/zygote/zygote_linux.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <string.h> 8 #include <string.h>
9 #include <sys/socket.h> 9 #include <sys/socket.h>
10 #include <sys/types.h> 10 #include <sys/types.h>
(...skipping 18 matching lines...) Expand all
29 #include "content/common/sandbox_linux/sandbox_linux.h" 29 #include "content/common/sandbox_linux/sandbox_linux.h"
30 #include "content/common/set_process_title.h" 30 #include "content/common/set_process_title.h"
31 #include "content/common/zygote_commands_linux.h" 31 #include "content/common/zygote_commands_linux.h"
32 #include "content/public/common/content_descriptors.h" 32 #include "content/public/common/content_descriptors.h"
33 #include "content/public/common/result_codes.h" 33 #include "content/public/common/result_codes.h"
34 #include "content/public/common/sandbox_linux.h" 34 #include "content/public/common/sandbox_linux.h"
35 #include "content/public/common/send_zygote_child_ping_linux.h" 35 #include "content/public/common/send_zygote_child_ping_linux.h"
36 #include "content/public/common/zygote_fork_delegate_linux.h" 36 #include "content/public/common/zygote_fork_delegate_linux.h"
37 #include "ipc/ipc_channel.h" 37 #include "ipc/ipc_channel.h"
38 #include "ipc/ipc_switches.h" 38 #include "ipc/ipc_switches.h"
39 #include "sandbox/linux/services/credentials.h"
40 #include "sandbox/linux/services/namespace_sandbox.h"
41 39
42 // See http://code.google.com/p/chromium/wiki/LinuxZygote 40 // See http://code.google.com/p/chromium/wiki/LinuxZygote
43 41
44 namespace content { 42 namespace content {
45 43
46 namespace { 44 namespace {
47 45
48 // NOP function. See below where this handler is installed. 46 // NOP function. See below where this handler is installed.
49 void SIGCHLDHandler(int signal) { 47 void SIGCHLDHandler(int signal) {
50 } 48 }
51 49
52 // On Linux, when a process is the init process of a PID namespace, it cannot be
53 // terminated by signals like SIGTERM or SIGINT, since they are ignored unless
54 // we register a handler for them. In the handlers, we exit with this special
55 // exit code that GetTerminationStatus understands to mean that we were
56 // terminated by an external signal.
57 const int kKilledExitCode = 0x80;
58 const int kUnexpectedExitCode = 0x81;
59
60 int LookUpFd(const base::GlobalDescriptors::Mapping& fd_mapping, uint32_t key) { 50 int LookUpFd(const base::GlobalDescriptors::Mapping& fd_mapping, uint32_t key) {
61 for (size_t index = 0; index < fd_mapping.size(); ++index) { 51 for (size_t index = 0; index < fd_mapping.size(); ++index) {
62 if (fd_mapping[index].key == key) 52 if (fd_mapping[index].key == key)
63 return fd_mapping[index].fd; 53 return fd_mapping[index].fd;
64 } 54 }
65 return -1; 55 return -1;
66 } 56 }
67 57
68 void CreatePipe(base::ScopedFD* read_pipe, base::ScopedFD* write_pipe) { 58 void CreatePipe(base::ScopedFD* read_pipe, base::ScopedFD* write_pipe) {
69 int raw_pipe[2]; 59 int raw_pipe[2];
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the 97 // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the
108 // browser on it. 98 // browser on it.
109 // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel. 99 // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel.
110 // See http://code.google.com/p/chromium/wiki/LinuxSandboxIPC 100 // See http://code.google.com/p/chromium/wiki/LinuxSandboxIPC
111 101
112 // We need to accept SIGCHLD, even though our handler is a no-op because 102 // We need to accept SIGCHLD, even though our handler is a no-op because
113 // otherwise we cannot wait on children. (According to POSIX 2001.) 103 // otherwise we cannot wait on children. (According to POSIX 2001.)
114 struct sigaction action; 104 struct sigaction action;
115 memset(&action, 0, sizeof(action)); 105 memset(&action, 0, sizeof(action));
116 action.sa_handler = &SIGCHLDHandler; 106 action.sa_handler = &SIGCHLDHandler;
117 PCHECK(sigaction(SIGCHLD, &action, NULL) == 0); 107 CHECK(sigaction(SIGCHLD, &action, NULL) == 0);
118 108
119 if (UsingSUIDSandbox() || UsingNSSandbox()) { 109 if (UsingSUIDSandbox() || UsingNSSandbox()) {
120 // Let the ZygoteHost know we are ready to go. 110 // Let the ZygoteHost know we are ready to go.
121 // The receiving code is in content/browser/zygote_host_linux.cc. 111 // The receiving code is in content/browser/zygote_host_linux.cc.
122 bool r = UnixDomainSocket::SendMsg(kZygoteSocketPairFd, 112 bool r = UnixDomainSocket::SendMsg(kZygoteSocketPairFd,
123 kZygoteHelloMessage, 113 kZygoteHelloMessage,
124 sizeof(kZygoteHelloMessage), 114 sizeof(kZygoteHelloMessage),
125 std::vector<int>()); 115 std::vector<int>());
126 #if defined(OS_CHROMEOS) 116 #if defined(OS_CHROMEOS)
127 LOG_IF(WARNING, !r) << "Sending zygote magic failed"; 117 LOG_IF(WARNING, !r) << "Sending zygote magic failed";
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 // We don't know if the process is dying, so get its status but don't 298 // We don't know if the process is dying, so get its status but don't
309 // wait. 299 // wait.
310 *status = base::GetTerminationStatus(child, exit_code); 300 *status = base::GetTerminationStatus(child, exit_code);
311 } 301 }
312 } 302 }
313 // Successfully got a status for |real_pid|. 303 // Successfully got a status for |real_pid|.
314 if (*status != base::TERMINATION_STATUS_STILL_RUNNING) { 304 if (*status != base::TERMINATION_STATUS_STILL_RUNNING) {
315 // Time to forget about this process. 305 // Time to forget about this process.
316 process_info_map_.erase(real_pid); 306 process_info_map_.erase(real_pid);
317 } 307 }
318
319 if (WIFEXITED(*exit_code) && WEXITSTATUS(*exit_code) == kKilledExitCode) {
320 *status = base::TERMINATION_STATUS_PROCESS_WAS_KILLED;
321 }
322
323 return true; 308 return true;
324 } 309 }
325 310
326 void Zygote::HandleGetTerminationStatus(int fd, 311 void Zygote::HandleGetTerminationStatus(int fd,
327 PickleIterator iter) { 312 PickleIterator iter) {
328 bool known_dead; 313 bool known_dead;
329 base::ProcessHandle child_requested; 314 base::ProcessHandle child_requested;
330 315
331 if (!iter.ReadBool(&known_dead) || !iter.ReadInt(&child_requested)) { 316 if (!iter.ReadBool(&known_dead) || !iter.ReadInt(&child_requested)) {
332 LOG(WARNING) << "Error parsing GetTerminationStatus request " 317 LOG(WARNING) << "Error parsing GetTerminationStatus request "
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 } 368 }
384 std::vector<int> fds; 369 std::vector<int> fds;
385 fds.push_back(ipc_channel_fd); // kBrowserFDIndex 370 fds.push_back(ipc_channel_fd); // kBrowserFDIndex
386 fds.push_back(pid_oracle.get()); // kPIDOracleFDIndex 371 fds.push_back(pid_oracle.get()); // kPIDOracleFDIndex
387 pid = helper->Fork(process_type, fds, channel_id); 372 pid = helper->Fork(process_type, fds, channel_id);
388 373
389 // Helpers should never return in the child process. 374 // Helpers should never return in the child process.
390 CHECK_NE(pid, 0); 375 CHECK_NE(pid, 0);
391 } else { 376 } else {
392 CreatePipe(&read_pipe, &write_pipe); 377 CreatePipe(&read_pipe, &write_pipe);
393 if (sandbox_flags_ & kSandboxLinuxPIDNS && 378 // This is roughly equivalent to a fork(). We are using ForkWithFlags mainly
394 sandbox_flags_ & kSandboxLinuxUserNS) { 379 // to give it some more diverse test coverage.
395 pid = sandbox::NamespaceSandbox::ForkInNewPidNamespace( 380 pid = base::ForkWithFlags(SIGCHLD, nullptr, nullptr);
396 /*drop_capabilities_in_child=*/true);
397 } else {
398 pid = fork();
399 }
400 } 381 }
401 382
402 if (pid == 0) { 383 if (pid == 0) {
403 // If the process is the init process inside a PID namespace, it must have
404 // explicit signal handlers.
405 if (getpid() == 1) {
406 for (const int sig : {SIGINT, SIGTERM}) {
407 sandbox::NamespaceSandbox::InstallTerminationSignalHandler(
408 sig, kKilledExitCode);
409 }
410
411 static const int kUnexpectedSignals[] = {
412 SIGHUP, SIGQUIT, SIGABRT, SIGPIPE, SIGUSR1, SIGUSR2,
413 };
414 for (const int sig : kUnexpectedSignals) {
415 sandbox::NamespaceSandbox::InstallTerminationSignalHandler(
416 sig, kUnexpectedExitCode);
417 }
418 }
419
420 // In the child process. 384 // In the child process.
421 write_pipe.reset(); 385 write_pipe.reset();
422 386
423 // Ping the PID oracle socket so the browser can find our PID. 387 // Ping the PID oracle socket so the browser can find our PID.
424 CHECK(SendZygoteChildPing(pid_oracle.get())); 388 CHECK(SendZygoteChildPing(pid_oracle.get()));
425 389
426 // Now read back our real PID from the zygote. 390 // Now read back our real PID from the zygote.
427 base::ProcessId real_pid; 391 base::ProcessId real_pid;
428 if (!base::ReadFromFD(read_pipe.get(), 392 if (!base::ReadFromFD(read_pipe.get(),
429 reinterpret_cast<char*>(&real_pid), 393 reinterpret_cast<char*>(&real_pid),
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 PickleIterator iter) { 585 PickleIterator iter) {
622 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_))) != 586 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_))) !=
623 sizeof(sandbox_flags_)) { 587 sizeof(sandbox_flags_)) {
624 PLOG(ERROR) << "write"; 588 PLOG(ERROR) << "write";
625 } 589 }
626 590
627 return false; 591 return false;
628 } 592 }
629 593
630 } // namespace content 594 } // namespace content
OLDNEW
« no previous file with comments | « content/common/sandbox_linux/sandbox_linux.cc ('k') | content/zygote/zygote_main_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698