Index: content/zygote/zygote_main_linux.cc |
diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc |
index 9b6d0e85461d053689b699aa9c09c1a8f143229c..f9b821b0873e7486f9b9454b43f52ba8edfa5512 100644 |
--- a/content/zygote/zygote_main_linux.cc |
+++ b/content/zygote/zygote_main_linux.cc |
@@ -37,6 +37,7 @@ |
#include "content/public/common/zygote_fork_delegate_linux.h" |
#include "content/zygote/zygote_linux.h" |
#include "sandbox/linux/services/libc_urandom_override.h" |
+#include "sandbox/linux/suid/client/setuid_sandbox_client.h" |
#include "skia/ext/SkFontHost_fontconfig_control.h" |
#include "unicode/timezone.h" |
@@ -52,11 +53,6 @@ namespace content { |
// See http://code.google.com/p/chromium/wiki/LinuxZygote |
-// The SUID sandbox sets this environment variable to a file descriptor |
-// over which we can signal that we have completed our startup and can be |
-// chrooted. |
-static const char kSUIDSandboxVar[] = "SBX_D"; |
- |
// With SELinux we can carve out a precise sandbox, so we don't have to play |
// with intercepting libc calls. |
#if !defined(CHROMIUM_SELINUX) |
@@ -364,71 +360,31 @@ static bool CreateInitProcessReaper() { |
// This will set the *using_suid_sandbox variable to true if the SUID sandbox |
// is enabled. This does not necessarily exclude other types of sandboxing. |
-static bool EnterSandbox(bool* using_suid_sandbox, bool* has_started_new_init) { |
+static bool EnterSandbox(sandbox::SetuidSandboxClient* setuid_sandbox, |
+ bool* using_suid_sandbox, bool* has_started_new_init) { |
*using_suid_sandbox = false; |
*has_started_new_init = false; |
+ if (!setuid_sandbox) |
+ return false; |
PreSandboxInit(); |
SkiaFontConfigSetImplementation( |
new FontConfigIPC(Zygote::kMagicSandboxIPCDescriptor)); |
- const char* const sandbox_fd_string = getenv(kSUIDSandboxVar); |
- if (sandbox_fd_string) { |
- char* endptr; |
+ if (setuid_sandbox->IsSuidSandboxChild()) { |
// Use the SUID sandbox. This still allows the seccomp sandbox to |
// be enabled by the process later. |
*using_suid_sandbox = true; |
- // Check if the SUID sandbox provides the correct API version. |
- const char* const sandbox_api_string = |
- getenv(base::kSandboxEnvironmentApiProvides); |
- // Assume API version 0 if no environment was found |
- long sandbox_api_num = 0; |
- if (sandbox_api_string) { |
- errno = 0; |
- sandbox_api_num = strtol(sandbox_api_string, &endptr, 10); |
- if (errno || *endptr) { |
- return false; |
- } |
- } |
- |
- if (sandbox_api_num != base::kSUIDSandboxApiNumber) { |
+ if (!setuid_sandbox->IsSuidSandboxUpToDate()) { |
LOG(WARNING) << "You are using a wrong version of the setuid binary!\n" |
"Please read " |
"https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment." |
"\n\n"; |
} |
- // Get the file descriptor to signal the chroot helper. |
- errno = 0; |
- const long fd_long = strtol(sandbox_fd_string, &endptr, 10); |
- if (errno || !*sandbox_fd_string || *endptr || fd_long < 0 || |
- fd_long > INT_MAX) { |
- return false; |
- } |
- const int fd = fd_long; |
- |
- static const char kMsgChrootMe = 'C'; |
- static const char kMsgChrootSuccessful = 'O'; |
- |
- if (HANDLE_EINTR(write(fd, &kMsgChrootMe, 1)) != 1) { |
- LOG(ERROR) << "Failed to write to chroot pipe: " << errno; |
- return false; |
- } |
- |
- // We need to reap the chroot helper process in any event: |
- wait(NULL); |
- |
- char reply; |
- if (HANDLE_EINTR(read(fd, &reply, 1)) != 1) { |
- LOG(ERROR) << "Failed to read from chroot pipe: " << errno; |
- return false; |
- } |
- |
- if (reply != kMsgChrootSuccessful) { |
- LOG(ERROR) << "Error code reply from chroot helper"; |
+ if (!setuid_sandbox->ChrootMe()) |
return false; |
- } |
if (getpid() == 1) { |
// The setuid sandbox has created a new PID namespace and we need |
@@ -473,10 +429,14 @@ static bool EnterSandbox(bool* using_suid_sandbox, bool* has_started_new_init) { |
} |
#else // CHROMIUM_SELINUX |
-static bool EnterSandbox(bool* using_suid_sandbox, bool* has_started_new_init) { |
+static bool EnterSandbox(sandbox::SetuidSandboxClient* setuid_sandbox, |
+ bool* using_suid_sandbox, bool* has_started_new_init) { |
*using_suid_sandbox = false; |
*has_started_new_init = false; |
+ if (!setuid_sandbox) |
+ return false; |
+ |
PreSandboxInit(); |
SkiaFontConfigSetImplementation( |
new FontConfigIPC(Zygote::kMagicSandboxIPCDescriptor)); |
@@ -506,9 +466,17 @@ bool ZygoteMain(const MainFunctionParams& params, |
} |
#endif // SECCOMP_SANDBOX |
+ scoped_ptr<sandbox::SetuidSandboxClient> |
+ setuid_sandbox(sandbox::SetuidSandboxClient::Create()); |
+ |
+ if (setuid_sandbox == NULL) { |
+ LOG(FATAL) << "Failed to instantiate the setuid sandbox client."; |
+ return false; |
+ } |
+ |
if (forkdelegate != NULL) { |
VLOG(1) << "ZygoteMain: initializing fork delegate"; |
- forkdelegate->Init(getenv(kSUIDSandboxVar) != NULL, |
+ forkdelegate->Init(setuid_sandbox->IsSuidSandboxChild(), |
Zygote::kBrowserDescriptor, |
Zygote::kMagicSandboxIPCDescriptor); |
} else { |
@@ -518,7 +486,9 @@ bool ZygoteMain(const MainFunctionParams& params, |
// Turn on the SELinux or SUID sandbox. |
bool using_suid_sandbox = false; |
bool has_started_new_init = false; |
- if (!EnterSandbox(&using_suid_sandbox, &has_started_new_init)) { |
+ if (!EnterSandbox(setuid_sandbox.get(), |
+ &using_suid_sandbox, |
+ &has_started_new_init)) { |
LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: " |
<< errno << ")"; |
return false; |
@@ -527,9 +497,9 @@ bool ZygoteMain(const MainFunctionParams& params, |
int sandbox_flags = 0; |
if (using_suid_sandbox) { |
sandbox_flags |= kSandboxLinuxSUID; |
- if (getenv("SBX_PID_NS")) |
+ if (setuid_sandbox->IsInNewPIDNamespace()) |
sandbox_flags |= kSandboxLinuxPIDNS; |
- if (getenv("SBX_NET_NS")) |
+ if (setuid_sandbox->IsInNewNETNamespace()) |
sandbox_flags |= kSandboxLinuxNetNS; |
} |