| Index: content/browser/zygote_host/zygote_host_impl_linux.cc
|
| diff --git a/content/browser/zygote_host/zygote_host_impl_linux.cc b/content/browser/zygote_host/zygote_host_impl_linux.cc
|
| index 0da7da72da7fb67cde88d07b3abd89fcf364fe71..483cccf5d072382b87ae2ccbfe6a67a55c491f83 100644
|
| --- a/content/browser/zygote_host/zygote_host_impl_linux.cc
|
| +++ b/content/browser/zygote_host/zygote_host_impl_linux.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "content/browser/zygote_host/zygote_host_impl_linux.h"
|
|
|
| +#include <string.h>
|
| #include <sys/socket.h>
|
| #include <sys/stat.h>
|
| #include <sys/types.h>
|
| @@ -126,17 +127,22 @@ void ZygoteHostImpl::Init(const std::string& sandbox_cmd) {
|
| const int sfd = RenderSandboxHostLinux::GetInstance()->GetRendererSocket();
|
| fds_to_map.push_back(std::make_pair(sfd, GetSandboxFD()));
|
|
|
| - int dummy_fd = -1;
|
| + base::ScopedFD dummy_fd;
|
| if (using_suid_sandbox_) {
|
| scoped_ptr<sandbox::SetuidSandboxClient>
|
| sandbox_client(sandbox::SetuidSandboxClient::Create());
|
| sandbox_client->PrependWrapper(&cmd_line, &options);
|
| sandbox_client->SetupLaunchEnvironment();
|
|
|
| + // We no longer need this dummy socket for discovering the zygote's PID,
|
| + // but the sandbox is still hard-coded to expect a file descriptor at
|
| + // kZygoteIdFd. Fixing this requires a sandbox API change. :(
|
| CHECK_EQ(kZygoteIdFd, sandbox_client->GetUniqueToChildFileDescriptor());
|
| - dummy_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
| - CHECK(dummy_fd >= 0);
|
| - fds_to_map.push_back(std::make_pair(dummy_fd, kZygoteIdFd));
|
| + dummy_fd.reset(socket(AF_UNIX, SOCK_DGRAM, 0));
|
| + CHECK_GE(dummy_fd.get(), 0);
|
| + fds_to_map.push_back(std::make_pair(dummy_fd.get(), kZygoteIdFd));
|
| +
|
| + CHECK(UnixDomainSocket::EnableReceiveProcessId(fds[0]));
|
| }
|
|
|
| base::ProcessHandle process = -1;
|
| @@ -144,40 +150,24 @@ void ZygoteHostImpl::Init(const std::string& sandbox_cmd) {
|
| base::LaunchProcess(cmd_line.argv(), options, &process);
|
| CHECK(process != -1) << "Failed to launch zygote process";
|
|
|
| + dummy_fd.reset();
|
| +
|
| if (using_suid_sandbox_) {
|
| - // In the SUID sandbox, the real zygote is forked from the sandbox.
|
| - // We need to look for it.
|
| - // But first, wait for the zygote to tell us it's running.
|
| // The sending code is in content/browser/zygote_main_linux.cc.
|
| std::vector<int> fds_vec;
|
| - const int kExpectedLength = sizeof(kZygoteHelloMessage);
|
| + const size_t kExpectedLength = sizeof(kZygoteHelloMessage);
|
| char buf[kExpectedLength];
|
| - const ssize_t len = UnixDomainSocket::RecvMsg(fds[0], buf, sizeof(buf),
|
| - &fds_vec);
|
| - CHECK_EQ(kExpectedLength, len) << "Incorrect zygote magic length";
|
| - CHECK(0 == strcmp(buf, kZygoteHelloMessage)) << "Incorrect zygote hello";
|
| -
|
| - std::string inode_output;
|
| - ino_t inode = 0;
|
| - // Figure out the inode for |dummy_fd|, close |dummy_fd| on our end,
|
| - // and find the zygote process holding |dummy_fd|.
|
| - CHECK(base::FileDescriptorGetInode(&inode, dummy_fd))
|
| - << "Cannot get inode for dummy_fd " << dummy_fd;
|
| - close(dummy_fd);
|
| -
|
| - std::vector<std::string> get_inode_cmdline;
|
| - get_inode_cmdline.push_back(sandbox_binary_);
|
| - get_inode_cmdline.push_back(base::kFindInodeSwitch);
|
| - get_inode_cmdline.push_back(base::Int64ToString(inode));
|
| - CommandLine get_inode_cmd(get_inode_cmdline);
|
| - CHECK(base::GetAppOutput(get_inode_cmd, &inode_output))
|
| - << "Find inode command failed for inode " << inode;
|
| -
|
| - base::TrimWhitespaceASCII(inode_output, base::TRIM_ALL, &inode_output);
|
| - CHECK(base::StringToInt(inode_output, &pid_))
|
| - << "Invalid find inode output: " << inode_output;
|
| - CHECK(pid_ > 0) << "Did not find zygote process (using sandbox binary "
|
| - << sandbox_binary_ << ")";
|
| + const ssize_t len = UnixDomainSocket::RecvMsgWithPid(
|
| + fds[0], buf, sizeof(buf), &fds_vec, &pid_);
|
| + CHECK_EQ(kExpectedLength, static_cast<size_t>(len))
|
| + << "Incorrect zygote magic length";
|
| + CHECK_EQ(0, memcmp(buf, kZygoteHelloMessage, kExpectedLength))
|
| + << "Incorrect zygote hello";
|
| + CHECK_EQ(0U, fds_vec.size()) << "Zygote shouldn't send us any descriptors";
|
| + CHECK_GT(pid_, 1) << "Did not find zygote process";
|
| +
|
| + // TODO(mdempsky): Sanity check that pid_ is valid for our namespace. Linux
|
| + // kernels before 3.0 didn't translate across namespaces (crbug.com/357670).
|
|
|
| if (process != pid_) {
|
| // Reap the sandbox.
|
|
|