Index: components/nacl/loader/nacl_helper_linux.cc |
diff --git a/components/nacl/loader/nacl_helper_linux.cc b/components/nacl/loader/nacl_helper_linux.cc |
index a7c6615e51b11973b9c98d6d1f762de23d48fa31..68d0ff66ce6d93fa48574360e22a17e2fc85bf1c 100644 |
--- a/components/nacl/loader/nacl_helper_linux.cc |
+++ b/components/nacl/loader/nacl_helper_linux.cc |
@@ -32,17 +32,13 @@ |
#include "base/rand_util.h" |
#include "components/nacl/common/nacl_switches.h" |
#include "components/nacl/loader/nacl_listener.h" |
-#include "components/nacl/loader/nacl_sandbox_linux.h" |
-#include "components/nacl/loader/nonsfi/nonsfi_sandbox.h" |
+#include "components/nacl/loader/sandbox_linux/nacl_sandbox_linux.h" |
#include "content/public/common/content_descriptors.h" |
#include "content/public/common/zygote_fork_delegate_linux.h" |
#include "crypto/nss_util.h" |
#include "ipc/ipc_descriptors.h" |
#include "ipc/ipc_switches.h" |
-#include "sandbox/linux/services/credentials.h" |
#include "sandbox/linux/services/libc_urandom_override.h" |
-#include "sandbox/linux/services/thread_helpers.h" |
-#include "sandbox/linux/suid/client/setuid_sandbox_client.h" |
namespace { |
@@ -51,69 +47,6 @@ struct NaClLoaderSystemInfo { |
long number_of_cores; |
}; |
-// This is a poor man's check on whether we are sandboxed. |
-bool IsSandboxed() { |
- int proc_fd = open("/proc/self/exe", O_RDONLY); |
- if (proc_fd >= 0) { |
- close(proc_fd); |
- return false; |
- } |
- return true; |
-} |
- |
-void InitializeLayerOneSandbox() { |
- // Check that IsSandboxed() works. We should not be sandboxed at this point. |
- CHECK(!IsSandboxed()) << "Unexpectedly sandboxed!"; |
- scoped_ptr<sandbox::SetuidSandboxClient> |
- setuid_sandbox_client(sandbox::SetuidSandboxClient::Create()); |
- PCHECK(0 == IGNORE_EINTR(close( |
- setuid_sandbox_client->GetUniqueToChildFileDescriptor()))); |
- const bool suid_sandbox_child = setuid_sandbox_client->IsSuidSandboxChild(); |
- const bool is_init_process = 1 == getpid(); |
- CHECK_EQ(is_init_process, suid_sandbox_child); |
- |
- if (suid_sandbox_child) { |
- // Make sure that no directory file descriptor is open, as it would bypass |
- // the setuid sandbox model. |
- sandbox::Credentials credentials; |
- CHECK(!credentials.HasOpenDirectory(-1)); |
- |
- // Get sandboxed. |
- CHECK(setuid_sandbox_client->ChrootMe()); |
- CHECK(IsSandboxed()); |
- } |
-} |
- |
-void InitializeLayerTwoSandbox(bool uses_nonsfi_mode) { |
- if (uses_nonsfi_mode) { |
- const bool can_be_no_sandbox = CommandLine::ForCurrentProcess()->HasSwitch( |
- switches::kNaClDangerousNoSandboxNonSfi); |
- const bool setuid_sandbox_enabled = IsSandboxed(); |
- if (!setuid_sandbox_enabled) { |
- if (can_be_no_sandbox) |
- LOG(ERROR) << "DANGEROUS: Running non-SFI NaCl without SUID sandbox!"; |
- else |
- LOG(FATAL) << "SUID sandbox is mandatory for non-SFI NaCl"; |
- } |
- const bool bpf_sandbox_initialized = nacl::nonsfi::InitializeBPFSandbox(); |
- if (!bpf_sandbox_initialized) { |
- if (can_be_no_sandbox) { |
- LOG(ERROR) |
- << "DANGEROUS: Running non-SFI NaCl without seccomp-bpf sandbox!"; |
- } else { |
- LOG(FATAL) << "Could not initialize NaCl's second " |
- << "layer sandbox (seccomp-bpf) for non-SFI mode."; |
- } |
- } |
- } else { |
- const bool bpf_sandbox_initialized = InitializeBPFSandbox(); |
- if (!bpf_sandbox_initialized) { |
- LOG(ERROR) << "Could not initialize NaCl's second " |
- << "layer sandbox (seccomp-bpf) for SFI mode."; |
- } |
- } |
-} |
- |
// Replace |file_descriptor| with the reading end of a closed pipe. |
void ReplaceFDWithDummy(int file_descriptor) { |
// Make sure that file_descriptor is an open descriptor. |
@@ -130,7 +63,9 @@ void ReplaceFDWithDummy(int file_descriptor) { |
// if (!child) { |
void BecomeNaClLoader(const std::vector<int>& child_fds, |
const NaClLoaderSystemInfo& system_info, |
- bool uses_nonsfi_mode) { |
+ bool uses_nonsfi_mode, |
+ nacl::NaClSandbox* nacl_sandbox) { |
+ DCHECK(nacl_sandbox); |
VLOG(1) << "NaCl loader: setting up IPC descriptor"; |
// Close or shutdown IPC channels that we don't need anymore. |
PCHECK(0 == IGNORE_EINTR(close(kNaClZygoteDescriptor))); |
@@ -149,7 +84,12 @@ void BecomeNaClLoader(const std::vector<int>& child_fds, |
ReplaceFDWithDummy(sandbox_ipc_channel); |
} |
- InitializeLayerTwoSandbox(uses_nonsfi_mode); |
+ // Finish layer-1 sandbox initialization and initialize the layer-2 sandbox. |
+ CHECK(!nacl_sandbox->HasOpenDirectory()); |
+ nacl_sandbox->InitializeLayerTwoSandbox(uses_nonsfi_mode); |
+ nacl_sandbox->SealLayerOneSandbox(); |
+ nacl_sandbox->CheckSandboxingStateWithPolicy(); |
+ |
base::GlobalDescriptors::GetInstance()->Set( |
kPrimaryIPCChannel, |
child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]); |
@@ -167,6 +107,7 @@ void BecomeNaClLoader(const std::vector<int>& child_fds, |
void ChildNaClLoaderInit(const std::vector<int>& child_fds, |
const NaClLoaderSystemInfo& system_info, |
bool uses_nonsfi_mode, |
+ nacl::NaClSandbox* nacl_sandbox, |
const std::string& channel_id) { |
const int parent_fd = child_fds[content::ZygoteForkDelegate::kParentFDIndex]; |
const int dummy_fd = child_fds[content::ZygoteForkDelegate::kDummyFDIndex]; |
@@ -199,7 +140,7 @@ void ChildNaClLoaderInit(const std::vector<int>& child_fds, |
if (IGNORE_EINTR(close(parent_fd)) != 0) |
LOG(ERROR) << "close(parent_fd) failed"; |
if (validack) { |
- BecomeNaClLoader(child_fds, system_info, uses_nonsfi_mode); |
+ BecomeNaClLoader(child_fds, system_info, uses_nonsfi_mode, nacl_sandbox); |
} else { |
LOG(ERROR) << "Failed to synch with zygote"; |
} |
@@ -211,6 +152,7 @@ void ChildNaClLoaderInit(const std::vector<int>& child_fds, |
// content/browser/zygote_main_linux.cc:ForkWithRealPid() |
bool HandleForkRequest(const std::vector<int>& child_fds, |
const NaClLoaderSystemInfo& system_info, |
+ nacl::NaClSandbox* nacl_sandbox, |
PickleIterator* input_iter, |
Pickle* output_pickle) { |
bool uses_nonsfi_mode; |
@@ -238,7 +180,8 @@ bool HandleForkRequest(const std::vector<int>& child_fds, |
} |
if (child_pid == 0) { |
- ChildNaClLoaderInit(child_fds, system_info, uses_nonsfi_mode, channel_id); |
+ ChildNaClLoaderInit( |
+ child_fds, system_info, uses_nonsfi_mode, nacl_sandbox, channel_id); |
NOTREACHED(); |
} |
@@ -293,14 +236,15 @@ bool HonorRequestAndReply(int reply_fd, |
int command_type, |
const std::vector<int>& attached_fds, |
const NaClLoaderSystemInfo& system_info, |
+ nacl::NaClSandbox* nacl_sandbox, |
PickleIterator* input_iter) { |
Pickle write_pickle; |
bool have_to_reply = false; |
// Commands must write anything to send back to |write_pickle|. |
switch (command_type) { |
case nacl::kNaClForkRequest: |
- have_to_reply = HandleForkRequest(attached_fds, system_info, |
- input_iter, &write_pickle); |
+ have_to_reply = HandleForkRequest( |
+ attached_fds, system_info, nacl_sandbox, input_iter, &write_pickle); |
break; |
case nacl::kNaClGetTerminationStatusRequest: |
have_to_reply = |
@@ -324,14 +268,15 @@ bool HonorRequestAndReply(int reply_fd, |
// Read a request from the Zygote from |zygote_ipc_fd| and handle it. |
// Die on EOF from |zygote_ipc_fd|. |
bool HandleZygoteRequest(int zygote_ipc_fd, |
- const NaClLoaderSystemInfo& system_info) { |
+ const NaClLoaderSystemInfo& system_info, |
+ nacl::NaClSandbox* nacl_sandbox) { |
std::vector<int> fds; |
char buf[kNaClMaxIPCMessageLength]; |
const ssize_t msglen = UnixDomainSocket::RecvMsg(zygote_ipc_fd, |
&buf, sizeof(buf), &fds); |
// If the Zygote has started handling requests, we should be sandboxed via |
// the setuid sandbox. |
- if (!IsSandboxed()) { |
+ if (!nacl_sandbox->layer_one_enabled()) { |
LOG(ERROR) << "NaCl helper process running without a sandbox!\n" |
<< "Most likely you need to configure your SUID sandbox " |
<< "correctly"; |
@@ -352,8 +297,8 @@ bool HandleZygoteRequest(int zygote_ipc_fd, |
LOG(ERROR) << "Unable to read command from Zygote"; |
return false; |
} |
- return HonorRequestAndReply(zygote_ipc_fd, command_type, fds, system_info, |
- &read_iter); |
+ return HonorRequestAndReply( |
+ zygote_ipc_fd, command_type, fds, system_info, nacl_sandbox, &read_iter); |
} |
static const char kNaClHelperReservedAtZero[] = "reserved_at_zero"; |
@@ -470,13 +415,16 @@ int main(int argc, char* argv[]) { |
CheckRDebug(argv[0]); |
+ scoped_ptr<nacl::NaClSandbox> nacl_sandbox(new nacl::NaClSandbox); |
// Make sure that the early initialization did not start any spurious |
// threads. |
#if !defined(THREAD_SANITIZER) |
- CHECK(sandbox::ThreadHelpers::IsSingleThreaded(-1)); |
+ CHECK(nacl_sandbox->IsSingleThreaded()); |
#endif |
- InitializeLayerOneSandbox(); |
+ const bool is_init_process = 1 == getpid(); |
+ nacl_sandbox->InitializeLayerOneSandbox(); |
+ CHECK_EQ(is_init_process, nacl_sandbox->layer_one_enabled()); |
const std::vector<int> empty; |
// Send the zygote a message to let it know we are ready to help |
@@ -488,8 +436,8 @@ int main(int argc, char* argv[]) { |
// Now handle requests from the Zygote. |
while (true) { |
- bool request_handled = HandleZygoteRequest(kNaClZygoteDescriptor, |
- system_info); |
+ bool request_handled = HandleZygoteRequest( |
+ kNaClZygoteDescriptor, system_info, nacl_sandbox.get()); |
// Do not turn this into a CHECK() without thinking about robustness |
// against malicious IPC requests. |
DCHECK(request_handled); |