0

Add an API around zygoteHost so that chrome doesn't reach into the internal content implementation.

BUG=98716
Review URL: https://chromiumcodereview.appspot.com/9463029

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123604 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
jam@chromium.org
2012-02-25 00:29:15 +00:00
parent 0d00f12856
commit c2c68b1f0c
12 changed files with 128 additions and 90 deletions

@ -95,7 +95,6 @@ include_rules = [
"+content/browser/tab_contents/web_drag_source_gtk.h",
"+content/browser/tab_contents/web_drag_source_mac.h",
"+content/browser/trace_controller.h",
"+content/browser/zygote_host_linux.h",
# DO NOT ADD ANY MORE ITEMS TO THE ABOVE LIST!
"-content/common",

@ -34,7 +34,7 @@
#if defined(OS_POSIX) && !defined(OS_MACOSX)
#include "content/browser/renderer_host/render_sandbox_host_linux.h"
#include "content/browser/zygote_host_linux.h"
#include "content/public/browser/zygote_host_linux.h"
#endif
using content::BrowserChildProcessHostIterator;
@ -157,7 +157,7 @@ void MemoryDetails::CollectChildInfoOnUIThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
#if defined(OS_POSIX) && !defined(OS_MACOSX)
const pid_t zygote_pid = ZygoteHost::GetInstance()->pid();
const pid_t zygote_pid = content::ZygoteHost::GetInstance()->GetPid();
const pid_t sandbox_helper_pid = RenderSandboxHostLinux::GetInstance()->pid();
#endif

@ -18,8 +18,8 @@
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/url_constants.h"
#include "content/browser/zygote_host_linux.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/zygote_host_linux.h"
#include "content/public/common/process_type.h"
#include "grit/chromium_strings.h"
@ -239,7 +239,7 @@ void MemoryDetails::CollectProcessData(
}
std::vector<pid_t> current_browser_processes;
const pid_t zygote = ZygoteHost::GetInstance()->pid();
const pid_t zygote = content::ZygoteHost::GetInstance()->GetPid();
GetAllChildren(processes, getpid(), zygote, &current_browser_processes);
ProcessData current_browser;
GetProcessDataMemoryInformation(current_browser_processes, &current_browser);

@ -24,12 +24,12 @@
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/chrome_constants.h"
#include "content/browser/renderer_host/render_widget_host.h"
#include "content/browser/zygote_host_linux.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/zygote_host_linux.h"
#if !defined(OS_CHROMEOS)
#error This file only meant to be compiled on ChromeOS
@ -183,7 +183,7 @@ bool OomPriorityManager::CompareTabStats(TabStats first,
void OomPriorityManager::AdjustFocusedTabScoreOnFileThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_);
ZygoteHost::GetInstance()->AdjustRendererOOMScore(
content::ZygoteHost::GetInstance()->AdjustRendererOOMScore(
focused_tab_pid_, chrome::kLowestRendererOomScore);
pid_to_oom_score_[focused_tab_pid_] = chrome::kLowestRendererOomScore;
}
@ -330,7 +330,7 @@ void OomPriorityManager::AdjustOomPrioritiesOnFileThread(
score = static_cast<int>(priority + 0.5f);
it = pid_to_oom_score_.find(iterator->renderer_handle);
if (it == pid_to_oom_score_.end() || it->second != score) {
ZygoteHost::GetInstance()->AdjustRendererOOMScore(
content::ZygoteHost::GetInstance()->AdjustRendererOOMScore(
iterator->renderer_handle, score);
pid_to_oom_score_[iterator->renderer_handle] = score;
}

@ -79,9 +79,9 @@
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/version_loader.h"
#include "chrome/browser/oom_priority_manager.h"
#include "content/browser/zygote_host_linux.h"
#include "content/public/browser/zygote_host_linux.h"
#elif defined(OS_LINUX) || defined(OS_OPENBSD)
#include "content/browser/zygote_host_linux.h"
#include "content/public/browser/zygote_host_linux.h"
#endif
#if defined(USE_TCMALLOC)
@ -962,24 +962,24 @@ std::string AboutSandbox() {
data.append(l10n_util::GetStringUTF8(IDS_ABOUT_SANDBOX_TITLE));
data.append("</h1>");
const int status = ZygoteHost::GetInstance()->sandbox_status();
const int status = content::ZygoteHost::GetInstance()->GetSandboxStatus();
data.append("<table>");
AboutSandboxRow(&data, "", IDS_ABOUT_SANDBOX_SUID_SANDBOX,
status & ZygoteHost::kSandboxSUID);
status & content::ZygoteHost::kSandboxSUID);
AboutSandboxRow(&data, "&nbsp;&nbsp;", IDS_ABOUT_SANDBOX_PID_NAMESPACES,
status & ZygoteHost::kSandboxPIDNS);
status & content::ZygoteHost::kSandboxPIDNS);
AboutSandboxRow(&data, "&nbsp;&nbsp;", IDS_ABOUT_SANDBOX_NET_NAMESPACES,
status & ZygoteHost::kSandboxNetNS);
status & content::ZygoteHost::kSandboxNetNS);
AboutSandboxRow(&data, "", IDS_ABOUT_SANDBOX_SECCOMP_SANDBOX,
status & ZygoteHost::kSandboxSeccomp);
status & content::ZygoteHost::kSandboxSeccomp);
data.append("</table>");
bool good = ((status & ZygoteHost::kSandboxSUID) &&
(status & ZygoteHost::kSandboxPIDNS)) ||
(status & ZygoteHost::kSandboxSeccomp);
bool good = ((status & content::ZygoteHost::kSandboxSUID) &&
(status & content::ZygoteHost::kSandboxPIDNS)) ||
(status & content::ZygoteHost::kSandboxSeccomp);
if (good) {
data.append("<p style=\"color: green\">");
data.append(l10n_util::GetStringUTF8(IDS_ABOUT_SANDBOX_OK));

@ -68,7 +68,7 @@
#if defined(OS_POSIX) && !defined(OS_MACOSX)
#include <sys/stat.h>
#include "content/browser/renderer_host/render_sandbox_host_linux.h"
#include "content/browser/zygote_host_linux.h"
#include "content/browser/zygote_host_impl_linux.h"
#endif
#if defined(USE_X11)
@ -105,10 +105,8 @@ void SetupSandbox(const CommandLine& parsed_command_line) {
sandbox_cmd = sandbox_binary;
// Tickle the sandbox host and zygote host so they fork now.
RenderSandboxHostLinux* shost = RenderSandboxHostLinux::GetInstance();
shost->Init(sandbox_cmd);
ZygoteHost* zhost = ZygoteHost::GetInstance();
zhost->Init(sandbox_cmd);
RenderSandboxHostLinux::GetInstance()->Init(sandbox_cmd);
ZygoteHostImpl::GetInstance()->Init(sandbox_cmd);
}
#endif

@ -28,7 +28,7 @@
#elif defined(OS_POSIX)
#include "base/memory/singleton.h"
#include "content/browser/renderer_host/render_sandbox_host_linux.h"
#include "content/browser/zygote_host_linux.h"
#include "content/browser/zygote_host_impl_linux.h"
#endif
#if defined(OS_POSIX)
@ -140,9 +140,9 @@ class ChildProcessLauncher::Context
mapping.push_back(std::pair<uint32_t, int>(kCrashDumpSignal,
crash_signal_fd));
}
handle = ZygoteHost::GetInstance()->ForkRequest(cmd_line->argv(),
mapping,
process_type);
handle = ZygoteHostImpl::GetInstance()->ForkRequest(cmd_line->argv(),
mapping,
process_type);
} else
// Fall through to the normal posix case below when we're not zygoting.
#endif
@ -276,7 +276,7 @@ class ChildProcessLauncher::Context
if (zygote) {
// If the renderer was created via a zygote, we have to proxy the reaping
// through the zygote process.
ZygoteHost::GetInstance()->EnsureProcessTerminated(handle);
ZygoteHostImpl::GetInstance()->EnsureProcessTerminated(handle);
} else
#endif // !OS_MACOSX
{
@ -349,7 +349,7 @@ base::TerminationStatus ChildProcessLauncher::GetChildTerminationStatus(
}
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
if (context_->zygote_) {
context_->termination_status_ = ZygoteHost::GetInstance()->
context_->termination_status_ = ZygoteHostImpl::GetInstance()->
GetTerminationStatus(handle, &context_->exit_code_);
} else
#endif

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/zygote_host_linux.h"
#include "content/browser/zygote_host_impl_linux.h"
#include <sys/socket.h>
#include <sys/stat.h>
@ -58,7 +58,12 @@ static void SaveSUIDUnsafeEnvironmentVariables() {
}
}
ZygoteHost::ZygoteHost()
// static
content::ZygoteHost* content::ZygoteHost::GetInstance() {
return ZygoteHostImpl::GetInstance();
}
ZygoteHostImpl::ZygoteHostImpl()
: control_fd_(-1),
pid_(-1),
init_(false),
@ -66,17 +71,17 @@ ZygoteHost::ZygoteHost()
have_read_sandbox_status_word_(false),
sandbox_status_(0) {}
ZygoteHost::~ZygoteHost() {
ZygoteHostImpl::~ZygoteHostImpl() {
if (init_)
close(control_fd_);
}
// static
ZygoteHost* ZygoteHost::GetInstance() {
return Singleton<ZygoteHost>::get();
ZygoteHostImpl* ZygoteHostImpl::GetInstance() {
return Singleton<ZygoteHostImpl>::get();
}
void ZygoteHost::Init(const std::string& sandbox_cmd) {
void ZygoteHostImpl::Init(const std::string& sandbox_cmd) {
DCHECK(!init_);
init_ = true;
@ -221,7 +226,7 @@ void ZygoteHost::Init(const std::string& sandbox_cmd) {
// We don't wait for the reply. We'll read it in ReadReply.
}
ssize_t ZygoteHost::ReadReply(void* buf, size_t buf_len) {
ssize_t ZygoteHostImpl::ReadReply(void* buf, size_t buf_len) {
// At startup we send a kCmdGetSandboxStatus request to the zygote, but don't
// wait for the reply. Thus, the first time that we read from the zygote, we
// get the reply to that request.
@ -237,7 +242,7 @@ ssize_t ZygoteHost::ReadReply(void* buf, size_t buf_len) {
return HANDLE_EINTR(read(control_fd_, buf, buf_len));
}
pid_t ZygoteHost::ForkRequest(
pid_t ZygoteHostImpl::ForkRequest(
const std::vector<std::string>& argv,
const base::GlobalDescriptors::Mapping& mapping,
const std::string& process_type) {
@ -319,7 +324,8 @@ pid_t ZygoteHost::ForkRequest(
}
#if !defined(OS_OPENBSD)
void ZygoteHost::AdjustRendererOOMScore(base::ProcessHandle pid, int score) {
void ZygoteHostImpl::AdjustRendererOOMScore(base::ProcessHandle pid,
int score) {
// 1) You can't change the oom_score_adj of a non-dumpable process
// (EPERM) unless you're root. Because of this, we can't set the
// oom_adj from the browser process.
@ -387,7 +393,7 @@ void ZygoteHost::AdjustRendererOOMScore(base::ProcessHandle pid, int score) {
}
#endif
void ZygoteHost::EnsureProcessTerminated(pid_t process) {
void ZygoteHostImpl::EnsureProcessTerminated(pid_t process) {
DCHECK(init_);
Pickle pickle;
@ -398,7 +404,7 @@ void ZygoteHost::EnsureProcessTerminated(pid_t process) {
PLOG(ERROR) << "write";
}
base::TerminationStatus ZygoteHost::GetTerminationStatus(
base::TerminationStatus ZygoteHostImpl::GetTerminationStatus(
base::ProcessHandle handle,
int* exit_code) {
DCHECK(init_);
@ -443,3 +449,13 @@ base::TerminationStatus ZygoteHost::GetTerminationStatus(
return static_cast<base::TerminationStatus>(status);
}
pid_t ZygoteHostImpl::GetPid() const {
return pid_;
}
int ZygoteHostImpl::GetSandboxStatus() const {
if (have_read_sandbox_status_word_)
return sandbox_status_;
return 0;
}

@ -2,34 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_ZYGOTE_HOST_LINUX_H_
#define CONTENT_BROWSER_ZYGOTE_HOST_LINUX_H_
#ifndef CONTENT_BROWSER_ZYGOTE_HOST_IMPL_LINUX_H_
#define CONTENT_BROWSER_ZYGOTE_HOST_IMPL_LINUX_H_
#pragma once
#include <unistd.h>
#include <string>
#include <vector>
#include "base/global_descriptors_posix.h"
#include "base/process.h"
#include "base/process_util.h"
#include "base/synchronization/lock.h"
#include "content/common/content_export.h"
#include "content/public/browser/zygote_host_linux.h"
template<typename Type>
struct DefaultSingletonTraits;
static const char kZygoteMagic[] = "ZYGOTE_OK";
// http://code.google.com/p/chromium/wiki/LinuxZygote
// The zygote host is the interface, in the browser process, to the zygote
// process.
class CONTENT_EXPORT ZygoteHost {
class CONTENT_EXPORT ZygoteHostImpl : public content::ZygoteHost {
public:
// Returns the singleton instance.
static ZygoteHost* GetInstance();
static ZygoteHostImpl* GetInstance();
void Init(const std::string& sandbox_cmd);
@ -56,34 +49,16 @@ class CONTENT_EXPORT ZygoteHost {
kCmdGetSandboxStatus = 3, // Read a bitmask of kSandbox*
};
// These form a bitmask which describes the conditions of the sandbox that
// the zygote finds itself in.
enum {
kSandboxSUID = 1 << 0, // SUID sandbox active
kSandboxPIDNS = 1 << 1, // SUID sandbox is using the PID namespace
kSandboxNetNS = 1 << 2, // SUID sandbox is using the network namespace
kSandboxSeccomp = 1 << 3, // seccomp sandbox active.
};
pid_t pid() const { return pid_; }
// Returns an int which is a bitmask of kSandbox* values. Only valid after
// the first render has been forked.
int sandbox_status() const {
if (have_read_sandbox_status_word_)
return sandbox_status_;
return 0;
}
// Adjust the OOM score of the given renderer's PID. The allowed
// range for the score is [0, 1000], where higher values are more
// likely to be killed by the OOM killer.
void AdjustRendererOOMScore(base::ProcessHandle process_handle, int score);
// ZygoteHost implementation:
virtual pid_t GetPid() const OVERRIDE;
virtual int GetSandboxStatus() const OVERRIDE;
virtual void AdjustRendererOOMScore(base::ProcessHandle process_handle,
int score) OVERRIDE;
private:
friend struct DefaultSingletonTraits<ZygoteHost>;
ZygoteHost();
~ZygoteHost();
friend struct DefaultSingletonTraits<ZygoteHostImpl>;
ZygoteHostImpl();
virtual ~ZygoteHostImpl();
ssize_t ReadReply(void* buf, size_t buflen);
@ -100,4 +75,4 @@ class CONTENT_EXPORT ZygoteHost {
int sandbox_status_;
};
#endif // CONTENT_BROWSER_ZYGOTE_HOST_LINUX_H_
#endif // CONTENT_BROWSER_ZYGOTE_HOST_IMPL_LINUX_H_

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/zygote_host_linux.h"
#include "content/browser/zygote_host_impl_linux.h"
#include <dlfcn.h>
#include <fcntl.h>
@ -174,21 +174,21 @@ class Zygote {
int kind;
if (pickle.ReadInt(&iter, &kind)) {
switch (kind) {
case ZygoteHost::kCmdFork:
case ZygoteHostImpl::kCmdFork:
// This function call can return multiple times, once per fork().
return HandleForkRequest(fd, pickle, iter, fds);
case ZygoteHost::kCmdReap:
case ZygoteHostImpl::kCmdReap:
if (!fds.empty())
break;
HandleReapRequest(fd, pickle, iter);
return false;
case ZygoteHost::kCmdGetTerminationStatus:
case ZygoteHostImpl::kCmdGetTerminationStatus:
if (!fds.empty())
break;
HandleGetTerminationStatus(fd, pickle, iter);
return false;
case ZygoteHost::kCmdGetSandboxStatus:
case ZygoteHostImpl::kCmdGetSandboxStatus:
HandleGetSandboxStatus(fd, pickle, iter);
return false;
default:
@ -846,11 +846,11 @@ bool ZygoteMain(const content::MainFunctionParams& params,
int sandbox_flags = 0;
if (getenv("SBX_D"))
sandbox_flags |= ZygoteHost::kSandboxSUID;
sandbox_flags |= ZygoteHostImpl::kSandboxSUID;
if (getenv("SBX_PID_NS"))
sandbox_flags |= ZygoteHost::kSandboxPIDNS;
sandbox_flags |= ZygoteHostImpl::kSandboxPIDNS;
if (getenv("SBX_NET_NS"))
sandbox_flags |= ZygoteHost::kSandboxNetNS;
sandbox_flags |= ZygoteHostImpl::kSandboxNetNS;
#if defined(SECCOMP_SANDBOX)
// The seccomp sandbox will be turned on when the renderers start. But we can
@ -867,7 +867,7 @@ bool ZygoteMain(const content::MainFunctionParams& params,
"sandboxing disabled.";
} else {
VLOG(1) << "Enabling experimental Seccomp sandbox.";
sandbox_flags |= ZygoteHost::kSandboxSeccomp;
sandbox_flags |= ZygoteHostImpl::kSandboxSeccomp;
}
}
#endif // SECCOMP_SANDBOX

@ -132,6 +132,7 @@
'public/browser/web_ui_message_handler.h',
'public/browser/worker_service.h',
'public/browser/worker_service_observer.h',
'public/browser/zygote_host_linux.h',
'browser/accessibility/browser_accessibility.cc',
'browser/accessibility/browser_accessibility.h',
'browser/accessibility/browser_accessibility_cocoa.h',
@ -691,8 +692,8 @@
'browser/worker_host/worker_process_host.h',
'browser/worker_host/worker_service_impl.cc',
'browser/worker_host/worker_service_impl.h',
'browser/zygote_host_linux.cc',
'browser/zygote_host_linux.h',
'browser/zygote_host_impl_linux.cc',
'browser/zygote_host_impl_linux.h',
'browser/zygote_main_linux.cc',
'<(SHARED_INTERMEDIATE_DIR)/webkit/grit/devtools_resources.h',
'<(SHARED_INTERMEDIATE_DIR)/webkit/grit/devtools_resources_map.cc',

@ -0,0 +1,49 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_PUBLIC_BROWSER_ZYGOTE_HOST_LINUX_H_
#define CONTENT_PUBLIC_BROWSER_ZYGOTE_HOST_LINUX_H_
#pragma once
#include <unistd.h>
#include "base/process.h"
#include "content/common/content_export.h"
namespace content {
// http://code.google.com/p/chromium/wiki/LinuxZygote
// The zygote host is the interface, in the browser process, to the zygote
// process.
class ZygoteHost {
public:
// Returns the singleton instance.
CONTENT_EXPORT static ZygoteHost* GetInstance();
// These form a bitmask which describes the conditions of the sandbox that
// the zygote finds itself in.
enum {
kSandboxSUID = 1 << 0, // SUID sandbox active
kSandboxPIDNS = 1 << 1, // SUID sandbox is using the PID namespace
kSandboxNetNS = 1 << 2, // SUID sandbox is using the network namespace
kSandboxSeccomp = 1 << 3, // seccomp sandbox active.
};
virtual pid_t GetPid() const = 0;
// Returns an int which is a bitmask of kSandbox* values. Only valid after
// the first render has been forked.
virtual int GetSandboxStatus() const = 0;
// Adjust the OOM score of the given renderer's PID. The allowed
// range for the score is [0, 1000], where higher values are more
// likely to be killed by the OOM killer.
virtual void AdjustRendererOOMScore(base::ProcessHandle process_handle,
int score) = 0;
};
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_ZYGOTE_HOST_LINUX_H_