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

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

Issue 1158793003: Enable one PID namespace per process for NaCl processes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Enable PID namespace per process for nonsfi newlib NaCl as well. Created 5 years, 6 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
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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 // See http://code.google.com/p/chromium/wiki/LinuxZygote 42 // See http://code.google.com/p/chromium/wiki/LinuxZygote
43 43
44 namespace content { 44 namespace content {
45 45
46 namespace { 46 namespace {
47 47
48 // NOP function. See below where this handler is installed. 48 // NOP function. See below where this handler is installed.
49 void SIGCHLDHandler(int signal) { 49 void SIGCHLDHandler(int signal) {
50 } 50 }
51 51
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) { 52 int LookUpFd(const base::GlobalDescriptors::Mapping& fd_mapping, uint32_t key) {
61 for (size_t index = 0; index < fd_mapping.size(); ++index) { 53 for (size_t index = 0; index < fd_mapping.size(); ++index) {
62 if (fd_mapping[index].key == key) 54 if (fd_mapping[index].key == key)
63 return fd_mapping[index].fd; 55 return fd_mapping[index].fd;
64 } 56 }
65 return -1; 57 return -1;
66 } 58 }
67 59
68 void CreatePipe(base::ScopedFD* read_pipe, base::ScopedFD* write_pipe) { 60 void CreatePipe(base::ScopedFD* read_pipe, base::ScopedFD* write_pipe) {
69 int raw_pipe[2]; 61 int raw_pipe[2];
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 // wait. 301 // wait.
310 *status = base::GetTerminationStatus(child, exit_code); 302 *status = base::GetTerminationStatus(child, exit_code);
311 } 303 }
312 } 304 }
313 // Successfully got a status for |real_pid|. 305 // Successfully got a status for |real_pid|.
314 if (*status != base::TERMINATION_STATUS_STILL_RUNNING) { 306 if (*status != base::TERMINATION_STATUS_STILL_RUNNING) {
315 // Time to forget about this process. 307 // Time to forget about this process.
316 process_info_map_.erase(real_pid); 308 process_info_map_.erase(real_pid);
317 } 309 }
318 310
319 if (WIFEXITED(*exit_code) && WEXITSTATUS(*exit_code) == kKilledExitCode) { 311 if (WIFEXITED(*exit_code)) {
320 *status = base::TERMINATION_STATUS_PROCESS_WAS_KILLED; 312 const int exit_status = WEXITSTATUS(*exit_code);
313 if (exit_status == sandbox::NamespaceSandbox::SignalExitCode(SIGINT) ||
314 exit_status == sandbox::NamespaceSandbox::SignalExitCode(SIGTERM)) {
315 *status = base::TERMINATION_STATUS_PROCESS_WAS_KILLED;
316 }
321 } 317 }
322 318
323 return true; 319 return true;
324 } 320 }
325 321
326 void Zygote::HandleGetTerminationStatus(int fd, base::PickleIterator iter) { 322 void Zygote::HandleGetTerminationStatus(int fd, base::PickleIterator iter) {
327 bool known_dead; 323 bool known_dead;
328 base::ProcessHandle child_requested; 324 base::ProcessHandle child_requested;
329 325
330 if (!iter.ReadBool(&known_dead) || !iter.ReadInt(&child_requested)) { 326 if (!iter.ReadBool(&known_dead) || !iter.ReadInt(&child_requested)) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 383
388 // Helpers should never return in the child process. 384 // Helpers should never return in the child process.
389 CHECK_NE(pid, 0); 385 CHECK_NE(pid, 0);
390 } else { 386 } else {
391 CreatePipe(&read_pipe, &write_pipe); 387 CreatePipe(&read_pipe, &write_pipe);
392 if (sandbox_flags_ & kSandboxLinuxPIDNS && 388 if (sandbox_flags_ & kSandboxLinuxPIDNS &&
393 sandbox_flags_ & kSandboxLinuxUserNS) { 389 sandbox_flags_ & kSandboxLinuxUserNS) {
394 pid = sandbox::NamespaceSandbox::ForkInNewPidNamespace( 390 pid = sandbox::NamespaceSandbox::ForkInNewPidNamespace(
395 /*drop_capabilities_in_child=*/true); 391 /*drop_capabilities_in_child=*/true);
396 } else { 392 } else {
397 pid = fork(); 393 pid = sandbox::Credentials::ForkAndDropCapabilitiesInChild();
398 } 394 }
399 } 395 }
400 396
401 if (pid == 0) { 397 if (pid == 0) {
402 // If the process is the init process inside a PID namespace, it must have 398 // If the process is the init process inside a PID namespace, it must have
403 // explicit signal handlers. 399 // explicit signal handlers.
404 if (getpid() == 1) { 400 if (getpid() == 1) {
405 for (const int sig : {SIGINT, SIGTERM}) { 401 static const int kTerminationSignals[] = {
402 SIGINT, SIGTERM, SIGHUP, SIGQUIT, SIGABRT, SIGPIPE, SIGUSR1, SIGUSR2};
403 for (const int sig : kTerminationSignals) {
406 sandbox::NamespaceSandbox::InstallTerminationSignalHandler( 404 sandbox::NamespaceSandbox::InstallTerminationSignalHandler(
407 sig, kKilledExitCode); 405 sig, sandbox::NamespaceSandbox::SignalExitCode(sig));
408 }
409
410 static const int kUnexpectedSignals[] = {
411 SIGHUP, SIGQUIT, SIGABRT, SIGPIPE, SIGUSR1, SIGUSR2,
412 };
413 for (const int sig : kUnexpectedSignals) {
414 sandbox::NamespaceSandbox::InstallTerminationSignalHandler(
415 sig, kUnexpectedExitCode);
416 } 406 }
417 } 407 }
418 408
419 // In the child process. 409 // In the child process.
420 write_pipe.reset(); 410 write_pipe.reset();
421 411
422 // Ping the PID oracle socket so the browser can find our PID. 412 // Ping the PID oracle socket so the browser can find our PID.
423 CHECK(SendZygoteChildPing(pid_oracle.get())); 413 CHECK(SendZygoteChildPing(pid_oracle.get()));
424 414
425 // Now read back our real PID from the zygote. 415 // Now read back our real PID from the zygote.
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 bool Zygote::HandleGetSandboxStatus(int fd, base::PickleIterator iter) { 609 bool Zygote::HandleGetSandboxStatus(int fd, base::PickleIterator iter) {
620 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_))) != 610 if (HANDLE_EINTR(write(fd, &sandbox_flags_, sizeof(sandbox_flags_))) !=
621 sizeof(sandbox_flags_)) { 611 sizeof(sandbox_flags_)) {
622 PLOG(ERROR) << "write"; 612 PLOG(ERROR) << "write";
623 } 613 }
624 614
625 return false; 615 return false;
626 } 616 }
627 617
628 } // namespace content 618 } // namespace content
OLDNEW
« no previous file with comments | « components/nacl/loader/sandbox_linux/nacl_sandbox_linux.cc ('k') | sandbox/linux/services/credentials.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698