| 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 c8139bf25ecaa557b0627d5179e7a696ad58bcf1..8055fc8a3da710ef7ffe4923580493479e43fac0 100644
|
| --- a/components/nacl/loader/nacl_helper_linux.cc
|
| +++ b/components/nacl/loader/nacl_helper_linux.cc
|
| @@ -43,20 +43,48 @@ struct NaClLoaderSystemInfo {
|
| long number_of_cores;
|
| };
|
|
|
| -// The child must mimic the behavior of zygote_main_linux.cc on the child
|
| -// side of the fork. See zygote_main_linux.cc:HandleForkRequest from
|
| -// if (!child) {
|
| -void BecomeNaClLoader(const std::vector<int>& child_fds,
|
| - const NaClLoaderSystemInfo& system_info) {
|
| - VLOG(1) << "NaCl loader: setting up IPC descriptor";
|
| +// 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 InitializeSandbox(bool uses_nonsfi) {
|
| + const bool setuid_sandbox_enabled = IsSandboxed();
|
| + if (uses_nonsfi) {
|
| + CHECK(setuid_sandbox_enabled)
|
| + << "SUID sandbox is mandatory for non-SFI NaCl";
|
| + }
|
| // don't need zygote FD any more
|
| if (IGNORE_EINTR(close(kNaClZygoteDescriptor)) != 0)
|
| LOG(ERROR) << "close(kNaClZygoteDescriptor) failed.";
|
| - bool sandbox_initialized = InitializeBPFSandbox();
|
| - if (!sandbox_initialized) {
|
| + bool bpf_sandbox_initialized = false;
|
| + if (uses_nonsfi)
|
| + bpf_sandbox_initialized = InitializeBPFSandboxForNonSfi();
|
| + else
|
| + bpf_sandbox_initialized = InitializeBPFSandbox();
|
| + if (!bpf_sandbox_initialized) {
|
| LOG(ERROR) << "Could not initialize NaCl's second "
|
| - << "layer sandbox (seccomp-bpf).";
|
| + << "layer sandbox (seccomp-bpf).";
|
| + // We really depend on seccomp sandbox for non-SFI mode. We do not
|
| + // run any program without seccomp sandbox.
|
| + if (uses_nonsfi)
|
| + _exit(1);
|
| }
|
| +}
|
| +
|
| +// The child must mimic the behavior of zygote_main_linux.cc on the child
|
| +// side of the fork. See zygote_main_linux.cc:HandleForkRequest from
|
| +// if (!child) {
|
| +void BecomeNaClLoader(const std::vector<int>& child_fds,
|
| + const NaClLoaderSystemInfo& system_info,
|
| + bool uses_nonsfi) {
|
| + VLOG(1) << "NaCl loader: setting up IPC descriptor";
|
| + InitializeSandbox(uses_nonsfi);
|
| base::GlobalDescriptors::GetInstance()->Set(
|
| kPrimaryIPCChannel,
|
| child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]);
|
| @@ -71,7 +99,8 @@ void BecomeNaClLoader(const std::vector<int>& child_fds,
|
|
|
| // Start the NaCl loader in a child created by the NaCl loader Zygote.
|
| void ChildNaClLoaderInit(const std::vector<int>& child_fds,
|
| - const NaClLoaderSystemInfo& system_info) {
|
| + const NaClLoaderSystemInfo& system_info,
|
| + bool uses_nonsfi) {
|
| const int parent_fd = child_fds[content::ZygoteForkDelegate::kParentFDIndex];
|
| const int dummy_fd = child_fds[content::ZygoteForkDelegate::kDummyFDIndex];
|
| bool validack = false;
|
| @@ -103,7 +132,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);
|
| + BecomeNaClLoader(child_fds, system_info, uses_nonsfi);
|
| } else {
|
| LOG(ERROR) << "Failed to synch with zygote";
|
| }
|
| @@ -115,7 +144,14 @@ 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,
|
| + PickleIterator* input_iter,
|
| Pickle* output_pickle) {
|
| + bool uses_nonsfi;
|
| + if (!input_iter->ReadBool(&uses_nonsfi)) {
|
| + LOG(ERROR) << "Could not read uses_nonsfi status";
|
| + return false;
|
| + }
|
| +
|
| if (content::ZygoteForkDelegate::kNumPassedFDs != child_fds.size()) {
|
| LOG(ERROR) << "nacl_helper: unexpected number of fds, got "
|
| << child_fds.size();
|
| @@ -129,7 +165,7 @@ bool HandleForkRequest(const std::vector<int>& child_fds,
|
| }
|
|
|
| if (child_pid == 0) {
|
| - ChildNaClLoaderInit(child_fds, system_info);
|
| + ChildNaClLoaderInit(child_fds, system_info, uses_nonsfi);
|
| NOTREACHED();
|
| }
|
|
|
| @@ -176,16 +212,6 @@ bool HandleGetTerminationStatusRequest(PickleIterator* input_iter,
|
| return true;
|
| }
|
|
|
| -// 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;
|
| -}
|
| -
|
| // Honor a command |command_type|. Eventual command parameters are
|
| // available in |input_iter| and eventual file descriptors attached to
|
| // the command are in |attached_fds|.
|
| @@ -201,6 +227,7 @@ bool HonorRequestAndReply(int reply_fd,
|
| switch (command_type) {
|
| case nacl::kNaClForkRequest:
|
| have_to_reply = HandleForkRequest(attached_fds, system_info,
|
| + input_iter,
|
| &write_pickle);
|
| break;
|
| case nacl::kNaClGetTerminationStatusRequest:
|
|
|