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

Unified Diff: content/zygote/zygote_linux.cc

Issue 868233011: Start all children in their own PID namespace. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Only drop capabilities if we have any. 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 side-by-side diff with in-line comments
Download patch
Index: content/zygote/zygote_linux.cc
diff --git a/content/zygote/zygote_linux.cc b/content/zygote/zygote_linux.cc
index 5944f87aa1258dff7a908eb6d5a2d55cea93a05f..1a3fe6c889aff224c8c03fe5ab0c4c402b42495d 100644
--- a/content/zygote/zygote_linux.cc
+++ b/content/zygote/zygote_linux.cc
@@ -36,6 +36,7 @@
#include "content/public/common/zygote_fork_delegate_linux.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_switches.h"
+#include "sandbox/linux/services/credentials.h"
// See http://code.google.com/p/chromium/wiki/LinuxZygote
@@ -47,6 +48,20 @@ namespace {
void SIGCHLDHandler(int signal) {
}
+// On Linux, when a process is the init process of a PID namespace, it cannot be
+// terminated by signals like SIGTERM or SIGINT, since they are ignored unless
+// we register a handler for them. In the handlers, we exit with this special
+// exit code that GetTerminationStatus understands to mean that we were
+// terminated by an external signal.
+const int kKilledExitCode = 0x80;
+
+void TerminationSignalHandler(int signal) {
+ // Return a special exit code so that the process is detected as terminated by
+ // a signal. We cannot terminate ourself with a signal since we may be the
+ // init process in a PID namespace.
+ _exit(kKilledExitCode);
+}
+
int LookUpFd(const base::GlobalDescriptors::Mapping& fd_mapping, uint32_t key) {
for (size_t index = 0; index < fd_mapping.size(); ++index) {
if (fd_mapping[index].key == key)
@@ -275,12 +290,10 @@ bool Zygote::GetTerminationStatus(base::ProcessHandle real_pid,
bool known_dead,
base::TerminationStatus* status,
int* exit_code) {
-
ZygoteProcessInfo child_info;
if (!GetProcessInfo(real_pid, &child_info)) {
- LOG(ERROR) << "Zygote::GetTerminationStatus for unknown PID "
+ LOG(FATAL) << "Zygote::GetTerminationStatus for unknown PID "
<< real_pid;
- NOTREACHED();
return false;
}
// We know about |real_pid|.
@@ -305,6 +318,11 @@ bool Zygote::GetTerminationStatus(base::ProcessHandle real_pid,
// Time to forget about this process.
process_info_map_.erase(real_pid);
}
+
+ if (WIFEXITED(*exit_code) && WEXITSTATUS(*exit_code) == kKilledExitCode) {
+ *status = base::TERMINATION_STATUS_PROCESS_WAS_KILLED;
+ }
+
return true;
}
@@ -375,12 +393,30 @@ int Zygote::ForkWithRealPid(const std::string& process_type,
CHECK_NE(pid, 0);
} else {
CreatePipe(&read_pipe, &write_pipe);
- // This is roughly equivalent to a fork(). We are using ForkWithFlags mainly
- // to give it some more diverse test coverage.
- pid = base::ForkWithFlags(SIGCHLD, nullptr, nullptr);
+ int clone_flags = SIGCHLD;
+ if (sandbox_flags_ & kSandboxLinuxPIDNS &&
+ sandbox_flags_ & kSandboxLinuxUserNS) {
+ clone_flags |= CLONE_NEWPID;
jln (very slow on Chromium) 2015/02/25 21:32:48 I know there was some back and forth on this, but
rickyz (no longer on Chrome) 2015/03/21 01:35:31 I'm happy to not go out of my way to support peopl
+ }
+ pid = base::ForkWithFlags(clone_flags, nullptr, nullptr);
}
if (pid == 0) {
+ if (sandbox::Credentials::HasAnyCapability()) {
+ CHECK(sandbox::Credentials::DropAllCapabilities(
jln (very slow on Chromium) 2015/02/25 21:32:48 Why not always drop capabilities? Is it because p
rickyz (no longer on Chrome) 2015/03/21 01:35:31 Yeah, that's exactly the reason. I haven't address
+ LinuxSandbox::GetInstance()->proc_fd()));
+ }
+
+ // If the process is the init process inside a PID namespace, it must have
jln (very slow on Chromium) 2015/02/25 21:32:48 (I'm trying to figure out how we can re-factor the
rickyz (no longer on Chrome) 2015/03/21 01:35:31 Ugh, this signal handling stuff is so horrible. He
+ // explicit SIGTERM and SIGINT handlers.
+ if (getpid() == 1) {
+ struct sigaction action;
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = &TerminationSignalHandler;
+ PCHECK(sigaction(SIGINT, &action, nullptr) == 0);
+ PCHECK(sigaction(SIGTERM, &action, nullptr) == 0);
+ }
+
// In the child process.
write_pipe.reset();

Powered by Google App Engine
This is Rietveld 408576698