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

Unified Diff: components/nacl/loader/nacl_helper_linux.cc

Issue 250773003: NaCl Linux: create NaClSandbox class (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address nits. Created 6 years, 8 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 | « components/nacl/loader/OWNERS ('k') | components/nacl/loader/nacl_sandbox_linux.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« no previous file with comments | « components/nacl/loader/OWNERS ('k') | components/nacl/loader/nacl_sandbox_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698