summaryrefslogtreecommitdiffstats
path: root/chrome/browser/zygote_main_linux.cc
diff options
context:
space:
mode:
authorthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-04 04:22:47 +0000
committerthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-04 04:22:47 +0000
commit83a0cbe4af4408d7708bf54750aff66da80f3130 (patch)
treec75050f0d74936645b8b87f5e9aab9ded61e5bbc /chrome/browser/zygote_main_linux.cc
parentda11a4be3902edcdfb5c2f29925e068ebce36a67 (diff)
downloadchromium_src-83a0cbe4af4408d7708bf54750aff66da80f3130.zip
chromium_src-83a0cbe4af4408d7708bf54750aff66da80f3130.tar.gz
chromium_src-83a0cbe4af4408d7708bf54750aff66da80f3130.tar.bz2
Revert 30938 - Add support for getting the real process id from within the suid sandbox. The browser processes gets the real process ids, so they look correct in the task manager. When it asks the zygote to reap a process, we use the process ids internal to the sandbox.
While we are at it, reap the sandbox process after it clones the zygote and figure out zygote's actual process id. Save the actual process id rather than that of the sandbox. BUG=20012,20714,23072 TEST=Process IDs for renderers should be correct in the task manager and you should be able to use the end process button to kill them. Review URL: http://codereview.chromium.org/262020 Review URL: http://codereview.chromium.org/359001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30939 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/zygote_main_linux.cc')
-rw-r--r--chrome/browser/zygote_main_linux.cc133
1 files changed, 26 insertions, 107 deletions
diff --git a/chrome/browser/zygote_main_linux.cc b/chrome/browser/zygote_main_linux.cc
index b9839d3..ecf7291 100644
--- a/chrome/browser/zygote_main_linux.cc
+++ b/chrome/browser/zygote_main_linux.cc
@@ -3,25 +3,18 @@
// found in the LICENSE file.
#include <dlfcn.h>
+#include <unistd.h>
#include <sys/epoll.h>
-#include <sys/prctl.h>
-#include <sys/signal.h>
-#include <sys/socket.h>
#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/signal.h>
+#include <sys/prctl.h>
#include <sys/wait.h>
-#include <unistd.h>
-
-#if defined(CHROMIUM_SELINUX)
-#include <selinux/selinux.h>
-#include <selinux/context.h>
-#endif
#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/eintr_wrapper.h"
#include "base/global_descriptors_posix.h"
-#include "base/hash_tables.h"
-#include "base/linux_util.h"
#include "base/path_service.h"
#include "base/pickle.h"
#include "base/rand_util.h"
@@ -40,14 +33,16 @@
#include "skia/ext/SkFontHost_fontconfig_control.h"
+#if defined(CHROMIUM_SELINUX)
+#include <selinux/selinux.h>
+#include <selinux/context.h>
+#endif
+
#include "unicode/timezone.h"
// http://code.google.com/p/chromium/wiki/LinuxZygote
-static const int kBrowserDescriptor = 3;
static const int kMagicSandboxIPCDescriptor = 5;
-static const int kZygoteIdDescriptor = 7;
-static bool g_suid_sandbox_active = false;
// This is the object which implements the zygote. The ZygoteMain function,
// which is called from ChromeMain, at the the bottom and simple constructs one
@@ -57,7 +52,7 @@ class Zygote {
bool ProcessRequests() {
// A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the
// browser on it.
- // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel.
+ // A SOCK_DGRAM is installed in fd 4. This is the sandbox IPC channel.
// See http://code.google.com/p/chromium/wiki/LinuxSandboxIPC
// We need to accept SIGCHLD, even though our handler is a no-op because
@@ -67,17 +62,8 @@ class Zygote {
action.sa_handler = SIGCHLDHandler;
CHECK(sigaction(SIGCHLD, &action, NULL) == 0);
- if (g_suid_sandbox_active) {
- // Let the ZygoteHost know we are ready to go.
- // The receiving code is in chrome/browser/zygote_host_linux.cc.
- std::vector<int> empty;
- bool r = base::SendMsg(kBrowserDescriptor, kZygoteMagic,
- sizeof(kZygoteMagic), empty);
- CHECK(r) << "Sending zygote magic failed";
- }
-
for (;;) {
- if (HandleRequestFromBrowser(kBrowserDescriptor))
+ if (HandleRequestFromBrowser(3))
return true;
}
}
@@ -136,30 +122,20 @@ class Zygote {
return false;
}
- bool HandleReapRequest(int fd, const Pickle& pickle, void* iter) {
- base::ProcessId child;
- base::ProcessId actual_child;
+ bool HandleReapRequest(int fd, Pickle& pickle, void* iter) {
+ pid_t child;
if (!pickle.ReadInt(&iter, &child)) {
LOG(WARNING) << "Error parsing reap request from browser";
return false;
}
- if (g_suid_sandbox_active) {
- actual_child = real_pids_to_sandbox_pids[child];
- if (!actual_child)
- return false;
- real_pids_to_sandbox_pids.erase(child);
- } else {
- actual_child = child;
- }
-
- ProcessWatcher::EnsureProcessTerminated(actual_child);
+ ProcessWatcher::EnsureProcessTerminated(child);
return false;
}
- bool HandleDidProcessCrash(int fd, const Pickle& pickle, void* iter) {
+ bool HandleDidProcessCrash(int fd, Pickle& pickle, void* iter) {
base::ProcessHandle child;
if (!pickle.ReadInt(&iter, &child)) {
@@ -168,13 +144,7 @@ class Zygote {
}
bool child_exited;
- bool did_crash;
- if (g_suid_sandbox_active)
- child = real_pids_to_sandbox_pids[child];
- if (child)
- did_crash = base::DidProcessCrash(&child_exited, child);
- else
- did_crash = child_exited = false;
+ bool did_crash = base::DidProcessCrash(&child_exited, child);
Pickle write_pickle;
write_pickle.WriteBool(did_crash);
@@ -186,14 +156,12 @@ class Zygote {
// Handle a 'fork' request from the browser: this means that the browser
// wishes to start a new renderer.
- bool HandleForkRequest(int fd, const Pickle& pickle, void* iter,
+ bool HandleForkRequest(int fd, Pickle& pickle, void* iter,
std::vector<int>& fds) {
std::vector<std::string> args;
int argc, numfds;
base::GlobalDescriptors::Mapping mapping;
- base::ProcessId child;
- uint64_t dummy_inode = 0;
- int dummy_fd = -1;
+ pid_t child;
if (!pickle.ReadInt(&iter, &argc))
goto error;
@@ -218,22 +186,12 @@ class Zygote {
}
mapping.push_back(std::make_pair(
- static_cast<uint32_t>(kSandboxIPCChannel), kMagicSandboxIPCDescriptor));
-
- if (g_suid_sandbox_active) {
- dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0);
- if (dummy_fd < 0)
- goto error;
-
- if (!base::FileDescriptorGetInode(&dummy_inode, dummy_fd))
- goto error;
- }
+ static_cast<uint32_t>(kSandboxIPCChannel), 5));
child = fork();
if (!child) {
- close(kBrowserDescriptor); // our socket from the browser
- close(kZygoteIdDescriptor); // another socket from the browser
+ close(3); // our socket from the browser is in fd 3
Singleton<base::GlobalDescriptors>()->Reset(mapping);
// Reset the process-wide command line to our new command line.
@@ -242,59 +200,22 @@ class Zygote {
CommandLine::ForCurrentProcess()->InitFromArgv(args);
CommandLine::SetProcTitle();
return true;
- } else if (child < 0) {
- LOG(ERROR) << "Zygote could not fork";
- goto error;
}
- {
- base::ProcessId proc_id;
- if (g_suid_sandbox_active) {
- close(dummy_fd);
- dummy_fd = -1;
- uint8_t reply_buf[512];
- Pickle request;
- request.WriteInt(LinuxSandbox::METHOD_GET_CHILD_WITH_INODE);
- request.WriteUInt64(dummy_inode);
-
- const ssize_t r = base::SendRecvMsg(kMagicSandboxIPCDescriptor,
- reply_buf, sizeof(reply_buf),
- NULL, request);
- if (r == -1)
- goto error;
-
- Pickle reply(reinterpret_cast<char*>(reply_buf), r);
- void* iter2 = NULL;
- if (!reply.ReadInt(&iter2, &proc_id))
- goto error;
- real_pids_to_sandbox_pids[proc_id] = child;
- } else {
- proc_id = child;
- }
-
- for (std::vector<int>::const_iterator
- i = fds.begin(); i != fds.end(); ++i)
- close(*i);
+ for (std::vector<int>::const_iterator
+ i = fds.begin(); i != fds.end(); ++i)
+ close(*i);
- HANDLE_EINTR(write(fd, &proc_id, sizeof(proc_id)));
- return false;
- }
+ HANDLE_EINTR(write(fd, &child, sizeof(child)));
+ return false;
error:
- LOG(ERROR) << "Error parsing fork request from browser";
+ LOG(WARNING) << "Error parsing fork request from browser";
for (std::vector<int>::const_iterator
i = fds.begin(); i != fds.end(); ++i)
close(*i);
- if (dummy_fd >= 0)
- close(dummy_fd);
return false;
}
-
- // In the SUID sandbox, we try to use a new PID namespace. Thus the PIDs
- // fork() returns are not the real PIDs, so we need to map the Real PIDS
- // into the sandbox PID namespace.
- typedef base::hash_map<base::ProcessHandle, base::ProcessHandle> ProcessMap;
- ProcessMap real_pids_to_sandbox_pids;
};
// With SELinux we can carve out a precise sandbox, so we don't have to play
@@ -481,8 +402,6 @@ static bool EnterSandbox() {
// over which we can signal that we have completed our startup and can be
// chrooted.
- g_suid_sandbox_active = true;
-
char* endptr;
const long fd_long = strtol(sandbox_fd_string, &endptr, 10);
if (!*sandbox_fd_string || *endptr || fd_long < 0 || fd_long > INT_MAX)