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

Unified Diff: content/zygote/zygote_main_linux.cc

Issue 897723005: Allow using the namespace sandbox in zygote host. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More comments 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
« no previous file with comments | « content/public/common/content_switches.cc ('k') | sandbox/linux/services/namespace_sandbox.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/zygote/zygote_main_linux.cc
diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc
index 8f89580d42f6ed7a97b86e0e8651acf0905675a5..d1bd8cc076f44cef02f51a3033507e49a43b722e 100644
--- a/content/zygote/zygote_main_linux.cc
+++ b/content/zygote/zygote_main_linux.cc
@@ -39,8 +39,10 @@
#include "content/public/common/zygote_fork_delegate_linux.h"
#include "content/zygote/zygote_linux.h"
#include "crypto/nss_util.h"
+#include "sandbox/linux/services/credentials.h"
#include "sandbox/linux/services/init_process_reaper.h"
#include "sandbox/linux/services/libc_urandom_override.h"
+#include "sandbox/linux/services/namespace_sandbox.h"
#include "sandbox/linux/suid/client/setuid_sandbox_client.h"
#include "third_party/icu/source/i18n/unicode/timezone.h"
#include "third_party/skia/include/ports/SkFontConfigInterface.h"
@@ -399,6 +401,24 @@ static bool CreateInitProcessReaper(base::Closure* post_fork_parent_callback) {
return true;
}
+static bool MaybeSetProcessNonDumpable() {
+ const base::CommandLine& command_line =
+ *base::CommandLine::ForCurrentProcess();
+ if (command_line.HasSwitch(switches::kAllowSandboxDebugging)) {
+ // If sandbox debugging is allowed, install a handler for sandbox-related
+ // crash testing.
+ InstallSandboxCrashTestHandler();
+ return true;
+ }
+
+ if (prctl(PR_SET_DUMPABLE, 0) != 0) {
+ PLOG(ERROR) << "Failed to set non-dumpable flag";
+ return false;
+ }
+
+ return prctl(PR_GET_DUMPABLE) == 0;
+}
+
// Enter the setuid sandbox. This requires the current process to have been
// created through the setuid sandbox.
static bool EnterSuidSandbox(sandbox::SetuidSandboxClient* setuid_sandbox,
@@ -433,41 +453,27 @@ static bool EnterSuidSandbox(sandbox::SetuidSandboxClient* setuid_sandbox,
CHECK(CreateInitProcessReaper(post_fork_parent_callback));
}
-#if !defined(OS_OPENBSD)
- // Previously, we required that the binary be non-readable. This causes the
- // kernel to mark the process as non-dumpable at startup. The thinking was
- // that, although we were putting the renderers into a PID namespace (with
- // the SUID sandbox), they would nonetheless be in the /same/ PID
- // namespace. So they could ptrace each other unless they were non-dumpable.
- //
- // If the binary was readable, then there would be a window between process
- // startup and the point where we set the non-dumpable flag in which a
- // compromised renderer could ptrace attach.
- //
- // However, now that we have a zygote model, only the (trusted) zygote
- // exists at this point and we can set the non-dumpable flag which is
- // inherited by all our renderer children.
- //
- // Note: a non-dumpable process can't be debugged. To debug sandbox-related
- // issues, one can specify --allow-sandbox-debugging to let the process be
- // dumpable.
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- if (!command_line.HasSwitch(switches::kAllowSandboxDebugging)) {
- prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
- if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
- LOG(ERROR) << "Failed to set non-dumpable flag";
- return false;
- }
- } else {
- // If sandbox debugging is allowed, install a handler for sandbox-related
- // crash testing.
- InstallSandboxCrashTestHandler();
+ CHECK(MaybeSetProcessNonDumpable());
+ return true;
+}
+
+static void EnterNamespaceSandbox(base::Closure* post_fork_parent_callback) {
+ pid_t pid = getpid();
+ if (sandbox::NamespaceSandbox::InNewPidNamespace()) {
+ CHECK_EQ(1, pid);
}
-#endif
+ CHECK(sandbox::Credentials::MoveToNewUserNS());
+ CHECK(sandbox::Credentials::DropFileSystemAccess());
+ CHECK(sandbox::Credentials::DropAllCapabilities());
- return true;
+ // This needs to happen after moving to a new user NS, since doing so involves
+ // writing the UID/GID map.
+ CHECK(MaybeSetProcessNonDumpable());
+
+ if (pid == 1) {
+ CHECK(CreateInitProcessReaper(post_fork_parent_callback));
+ }
}
#if defined(ADDRESS_SANITIZER)
@@ -526,10 +532,8 @@ static pid_t ForkSanitizerCoverageHelper(
#endif // defined(ADDRESS_SANITIZER)
-// If |is_suid_sandbox_child|, then make sure that the setuid sandbox is
-// engaged.
static void EnterLayerOneSandbox(LinuxSandbox* linux_sandbox,
- bool is_suid_sandbox_child,
+ const bool using_layer1_sandbox,
base::Closure* post_fork_parent_callback) {
DCHECK(linux_sandbox);
@@ -542,10 +546,13 @@ static void EnterLayerOneSandbox(LinuxSandbox* linux_sandbox,
sandbox::SetuidSandboxClient* setuid_sandbox =
linux_sandbox->setuid_sandbox_client();
-
- if (is_suid_sandbox_child) {
+ if (setuid_sandbox->IsSuidSandboxChild()) {
CHECK(EnterSuidSandbox(setuid_sandbox, post_fork_parent_callback))
<< "Failed to enter setuid sandbox";
+ } else if (sandbox::NamespaceSandbox::InNewUserNamespace()) {
+ EnterNamespaceSandbox(post_fork_parent_callback);
+ } else {
+ CHECK(!using_layer1_sandbox);
}
}
@@ -583,9 +590,12 @@ bool ZygoteMain(const MainFunctionParams& params,
linux_sandbox->PreinitializeSandbox();
}
- const bool must_enable_setuid_sandbox =
+ const bool using_setuid_sandbox =
linux_sandbox->setuid_sandbox_client()->IsSuidSandboxChild();
- if (must_enable_setuid_sandbox) {
+ const bool using_namespace_sandbox =
+ sandbox::NamespaceSandbox::InNewUserNamespace();
+
+ if (using_setuid_sandbox) {
linux_sandbox->setuid_sandbox_client()->CloseDummyFile();
// Let the ZygoteHost know we're booting up.
@@ -597,10 +607,10 @@ bool ZygoteMain(const MainFunctionParams& params,
VLOG(1) << "ZygoteMain: initializing " << fork_delegates.size()
<< " fork delegates";
- for (ScopedVector<ZygoteForkDelegate>::iterator i = fork_delegates.begin();
- i != fork_delegates.end();
- ++i) {
- (*i)->Init(GetSandboxFD(), must_enable_setuid_sandbox);
+ const bool using_layer1_sandbox =
+ using_setuid_sandbox || using_namespace_sandbox;
+ for (ZygoteForkDelegate* fork_delegate : fork_delegates) {
+ fork_delegate->Init(GetSandboxFD(), using_layer1_sandbox);
}
const std::vector<int> sandbox_fds_to_close_post_fork =
@@ -613,7 +623,7 @@ bool ZygoteMain(const MainFunctionParams& params,
base::Bind(&CloseFds, fds_to_close_post_fork);
// Turn on the first layer of the sandbox if the configuration warrants it.
- EnterLayerOneSandbox(linux_sandbox, must_enable_setuid_sandbox,
+ EnterLayerOneSandbox(linux_sandbox, using_layer1_sandbox,
&post_fork_parent_callback);
// Extra children and file descriptors created that the Zygote must have
@@ -638,7 +648,7 @@ bool ZygoteMain(const MainFunctionParams& params,
int sandbox_flags = linux_sandbox->GetStatus();
bool setuid_sandbox_engaged = sandbox_flags & kSandboxLinuxSUID;
- CHECK_EQ(must_enable_setuid_sandbox, setuid_sandbox_engaged);
+ CHECK_EQ(using_setuid_sandbox, setuid_sandbox_engaged);
Zygote zygote(sandbox_flags, fork_delegates.Pass(), extra_children,
extra_fds);
« no previous file with comments | « content/public/common/content_switches.cc ('k') | sandbox/linux/services/namespace_sandbox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698