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

Unified Diff: content/zygote/zygote_linux.cc

Issue 240463005: Stop using chrome-sandbox to determine real pids (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix an embarassing number of compile errors Created 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/public/common/zygote_fork_delegate_linux.h ('k') | content/zygote/zygote_main_linux.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/zygote/zygote_linux.cc
diff --git a/content/zygote/zygote_linux.cc b/content/zygote/zygote_linux.cc
index 63c472fa7e7167340fafbc21a1ce135e605f2162..62b16b011299624e92c7a17235affb97281a1fcc 100644
--- a/content/zygote/zygote_linux.cc
+++ b/content/zygote/zygote_linux.cc
@@ -83,10 +83,10 @@ bool Zygote::ProcessRequests() {
if (UsingSUIDSandbox()) {
// Let the ZygoteHost know we are ready to go.
// The receiving code is in content/browser/zygote_host_linux.cc.
- std::vector<int> empty;
bool r = UnixDomainSocket::SendMsg(kZygoteSocketPairFd,
kZygoteHelloMessage,
- sizeof(kZygoteHelloMessage), empty);
+ sizeof(kZygoteHelloMessage),
+ std::vector<int>());
#if defined(OS_CHROMEOS)
LOG_IF(WARNING, !r) << "Sending zygote magic failed";
// Exit normally on chromeos because session manager may send SIGTERM
@@ -304,56 +304,42 @@ int Zygote::ForkWithRealPid(const std::string& process_type,
uma_name,
uma_sample,
uma_boundary_value));
- int dummy_fd;
- ino_t dummy_inode;
- int pipe_fds[2] = { -1, -1 };
- base::ProcessId pid = 0;
-
- dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0);
- if (dummy_fd < 0) {
- LOG(ERROR) << "Failed to create dummy FD";
- goto error;
- }
- if (!base::FileDescriptorGetInode(&dummy_inode, dummy_fd)) {
- LOG(ERROR) << "Failed to get inode for dummy FD";
- goto error;
- }
+
+ int pipe_fds[2] = {-1, -1};
if (pipe(pipe_fds) != 0) {
LOG(ERROR) << "Failed to create pipe";
- goto error;
+ return -1;
}
+ base::ScopedFD read_pipe(pipe_fds[0]);
+ base::ScopedFD write_pipe(pipe_fds[1]);
+ base::ProcessId pid = -1;
if (use_helper) {
std::vector<int> fds;
int ipc_channel_fd = LookUpFd(fd_mapping, kPrimaryIPCChannel);
if (ipc_channel_fd < 0) {
DLOG(ERROR) << "Failed to find kPrimaryIPCChannel in FD mapping";
- goto error;
+ return -1;
}
fds.push_back(ipc_channel_fd); // kBrowserFDIndex
- fds.push_back(dummy_fd); // kDummyFDIndex
- fds.push_back(pipe_fds[0]); // kParentFDIndex
+ fds.push_back(write_pipe.get()); // kParentFDIndex
pid = helper_->Fork(process_type, fds, channel_id);
} else {
pid = fork();
}
if (pid < 0) {
- goto error;
- } else if (pid == 0) {
+ return -1;
+ }
+ if (pid == 0) {
// In the child process.
- close(pipe_fds[1]);
+ read_pipe.reset();
+
base::ProcessId real_pid;
- // Wait until the parent process has discovered our PID. We
- // should not fork any child processes (which the seccomp
- // sandbox does) until then, because that can interfere with the
- // parent's discovery of our PID.
- if (!base::ReadFromFD(pipe_fds[0], reinterpret_cast<char*>(&real_pid),
- sizeof(real_pid))) {
- LOG(FATAL) << "Failed to synchronise with parent zygote process";
- }
- if (real_pid <= 0) {
- LOG(FATAL) << "Invalid pid from parent zygote";
+ if (!SendRealPidToZygote(write_pipe.get(), &real_pid)) {
+ LOG(FATAL) << "Failed to synchronise with parent process";
}
+ write_pipe.reset();
+
#if defined(OS_LINUX)
// Sandboxed processes need to send the global, non-namespaced PID when
// setting up an IPC channel to their parent.
@@ -363,78 +349,33 @@ int Zygote::ForkWithRealPid(const std::string& process_type,
base::debug::TraceLog::GetInstance()->SetProcessID(
static_cast<int>(real_pid));
#endif
- close(pipe_fds[0]);
- close(dummy_fd);
return 0;
- } else {
- // In the parent process.
- close(dummy_fd);
- dummy_fd = -1;
- close(pipe_fds[0]);
- pipe_fds[0] = -1;
- base::ProcessId real_pid;
- if (UsingSUIDSandbox()) {
- uint8_t reply_buf[512];
- Pickle request;
- request.WriteInt(LinuxSandbox::METHOD_GET_CHILD_WITH_INODE);
- request.WriteUInt64(dummy_inode);
-
- const ssize_t r = UnixDomainSocket::SendRecvMsg(
- GetSandboxFD(), reply_buf, sizeof(reply_buf), NULL,
- request);
- if (r == -1) {
- LOG(ERROR) << "Failed to get child process's real PID";
- goto error;
- }
-
- Pickle reply(reinterpret_cast<char*>(reply_buf), r);
- PickleIterator iter(reply);
- if (!reply.ReadInt(&iter, &real_pid))
- goto error;
- if (real_pid <= 0) {
- // METHOD_GET_CHILD_WITH_INODE failed. Did the child die already?
- LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed";
- goto error;
- }
- } else {
- // If no SUID sandbox is involved then no pid translation is
- // necessary.
- real_pid = pid;
- }
-
- // Now set-up this process to be tracked by the Zygote.
- if (process_info_map_.find(real_pid) != process_info_map_.end()) {
- LOG(ERROR) << "Already tracking PID " << real_pid;
- NOTREACHED();
- }
- process_info_map_[real_pid].internal_pid = pid;
- process_info_map_[real_pid].started_from_helper = use_helper;
-
- // If we're using a helper, we still need to let the child process know
- // we've discovered its real PID, but we don't actually reveal the PID.
- const base::ProcessId pid_for_child = use_helper ? 0 : real_pid;
- ssize_t written =
- HANDLE_EINTR(write(pipe_fds[1], &pid_for_child, sizeof(pid_for_child)));
- if (written != sizeof(pid_for_child)) {
- LOG(ERROR) << "Failed to synchronise with child process";
- goto error;
- }
- close(pipe_fds[1]);
- return real_pid;
}
- error:
- if (pid > 0) {
+ // In the parent process.
+ write_pipe.reset();
+
+ base::ProcessId real_pid;
+ if (!base::ReadFromFD(read_pipe.get(),
+ reinterpret_cast<char*>(&real_pid),
+ sizeof(real_pid))) {
+ LOG(ERROR) << "Failed to synchronise with child process";
+ // TODO(mdempsky): Dispatch to helper
if (waitpid(pid, NULL, WNOHANG) == -1)
LOG(ERROR) << "Failed to wait for process";
+ return -1;
}
- if (dummy_fd >= 0)
- close(dummy_fd);
- if (pipe_fds[0] >= 0)
- close(pipe_fds[0]);
- if (pipe_fds[1] >= 0)
- close(pipe_fds[1]);
- return -1;
+ read_pipe.reset();
+
+ // Now set-up this process to be tracked by the Zygote.
+ if (process_info_map_.find(real_pid) != process_info_map_.end()) {
+ LOG(ERROR) << "Already tracking PID " << real_pid;
+ NOTREACHED();
+ }
+ process_info_map_[real_pid].internal_pid = pid;
+ process_info_map_[real_pid].started_from_helper = use_helper;
+
+ return real_pid;
}
base::ProcessId Zygote::ReadArgsAndFork(const Pickle& pickle,
@@ -489,8 +430,6 @@ base::ProcessId Zygote::ReadArgsAndFork(const Pickle& pickle,
// This is the child process.
close(kZygoteSocketPairFd); // Our socket from the browser.
- if (UsingSUIDSandbox())
- close(kZygoteIdFd); // Another socket from the browser.
base::GlobalDescriptors::GetInstance()->Reset(mapping);
// Reset the process-wide command line to our new command line.
« no previous file with comments | « content/public/common/zygote_fork_delegate_linux.h ('k') | content/zygote/zygote_main_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698