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

Side by Side Diff: components/nacl/loader/nacl_helper_linux.cc

Issue 226033002: Ensure seccomp-bpf cannot be silently disabled for non-SFI NaCl (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // A mini-zygote specifically for Native Client. 5 // A mini-zygote specifically for Native Client.
6 6
7 #include "components/nacl/loader/nacl_helper_linux.h" 7 #include "components/nacl/loader/nacl_helper_linux.h"
8 8
9 #include <errno.h> 9 #include <errno.h>
10 #include <fcntl.h> 10 #include <fcntl.h>
(...skipping 10 matching lines...) Expand all
21 21
22 #include "base/at_exit.h" 22 #include "base/at_exit.h"
23 #include "base/command_line.h" 23 #include "base/command_line.h"
24 #include "base/logging.h" 24 #include "base/logging.h"
25 #include "base/message_loop/message_loop.h" 25 #include "base/message_loop/message_loop.h"
26 #include "base/posix/eintr_wrapper.h" 26 #include "base/posix/eintr_wrapper.h"
27 #include "base/posix/global_descriptors.h" 27 #include "base/posix/global_descriptors.h"
28 #include "base/posix/unix_domain_socket_linux.h" 28 #include "base/posix/unix_domain_socket_linux.h"
29 #include "base/process/kill.h" 29 #include "base/process/kill.h"
30 #include "base/rand_util.h" 30 #include "base/rand_util.h"
31 #include "components/nacl/common/nacl_switches.h"
31 #include "components/nacl/loader/nacl_listener.h" 32 #include "components/nacl/loader/nacl_listener.h"
32 #include "components/nacl/loader/nacl_sandbox_linux.h" 33 #include "components/nacl/loader/nacl_sandbox_linux.h"
33 #include "content/public/common/zygote_fork_delegate_linux.h" 34 #include "content/public/common/zygote_fork_delegate_linux.h"
34 #include "crypto/nss_util.h" 35 #include "crypto/nss_util.h"
35 #include "ipc/ipc_descriptors.h" 36 #include "ipc/ipc_descriptors.h"
36 #include "ipc/ipc_switches.h" 37 #include "ipc/ipc_switches.h"
37 #include "sandbox/linux/services/libc_urandom_override.h" 38 #include "sandbox/linux/services/libc_urandom_override.h"
38 39
39 namespace { 40 namespace {
40 41
41 struct NaClLoaderSystemInfo { 42 struct NaClLoaderSystemInfo {
42 size_t prereserved_sandbox_size; 43 size_t prereserved_sandbox_size;
43 long number_of_cores; 44 long number_of_cores;
44 }; 45 };
45 46
47 // This is a poor man's check on whether we are sandboxed.
48 bool IsSandboxed() {
49 int proc_fd = open("/proc/self/exe", O_RDONLY);
50 if (proc_fd >= 0) {
51 close(proc_fd);
52 return false;
53 }
54 return true;
55 }
56
57 void InitializeSandbox(bool uses_nonsfi_mode) {
58 if (uses_nonsfi_mode) {
59 const bool can_be_no_sandbox = CommandLine::ForCurrentProcess()->HasSwitch(
60 switches::kNaClDangerousNoSandboxNonSfi);
61 const bool setuid_sandbox_enabled = IsSandboxed();
62 if (!setuid_sandbox_enabled) {
63 if (can_be_no_sandbox)
64 LOG(ERROR) << "DANGEROUS: Running non-SFI NaCl without SUID sandbox!";
65 else
66 LOG(FATAL) << "SUID sandbox is mandatory for non-SFI NaCl";
67 }
68 const bool bpf_sandbox_initialized = InitializeBPFSandbox();
69 if (!bpf_sandbox_initialized) {
70 if (can_be_no_sandbox) {
71 LOG(ERROR)
72 << "DANGEROUS: Running non-SFI NaCl without seccomp-bpf sandbox!";
73 } else {
74 LOG(FATAL) << "Could not initialize NaCl's second "
75 << "layer sandbox (seccomp-bpf) for non-SFI mode.";
76 }
77 }
78 } else {
79 const bool bpf_sandbox_initialized = InitializeBPFSandbox();
80 if (!bpf_sandbox_initialized) {
81 LOG(ERROR) << "Could not initialize NaCl's second "
82 << "layer sandbox (seccomp-bpf) for SFI mode.";
83 }
84 }
85 }
86
46 // The child must mimic the behavior of zygote_main_linux.cc on the child 87 // The child must mimic the behavior of zygote_main_linux.cc on the child
47 // side of the fork. See zygote_main_linux.cc:HandleForkRequest from 88 // side of the fork. See zygote_main_linux.cc:HandleForkRequest from
48 // if (!child) { 89 // if (!child) {
49 void BecomeNaClLoader(const std::vector<int>& child_fds, 90 void BecomeNaClLoader(const std::vector<int>& child_fds,
50 const NaClLoaderSystemInfo& system_info, 91 const NaClLoaderSystemInfo& system_info,
51 bool uses_nonsfi_mode) { 92 bool uses_nonsfi_mode) {
52 VLOG(1) << "NaCl loader: setting up IPC descriptor"; 93 VLOG(1) << "NaCl loader: setting up IPC descriptor";
53 // don't need zygote FD any more 94 // don't need zygote FD any more
54 if (IGNORE_EINTR(close(kNaClZygoteDescriptor)) != 0) 95 if (IGNORE_EINTR(close(kNaClZygoteDescriptor)) != 0)
55 LOG(ERROR) << "close(kNaClZygoteDescriptor) failed."; 96 LOG(ERROR) << "close(kNaClZygoteDescriptor) failed.";
56 bool sandbox_initialized = InitializeBPFSandbox(); 97 InitializeSandbox(uses_nonsfi_mode);
57 if (!sandbox_initialized) {
58 LOG(ERROR) << "Could not initialize NaCl's second "
59 << "layer sandbox (seccomp-bpf).";
60 }
61 base::GlobalDescriptors::GetInstance()->Set( 98 base::GlobalDescriptors::GetInstance()->Set(
62 kPrimaryIPCChannel, 99 kPrimaryIPCChannel,
63 child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]); 100 child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]);
64 101
65 base::MessageLoopForIO main_message_loop; 102 base::MessageLoopForIO main_message_loop;
66 NaClListener listener; 103 NaClListener listener;
67 listener.set_uses_nonsfi_mode(uses_nonsfi_mode); 104 listener.set_uses_nonsfi_mode(uses_nonsfi_mode);
68 listener.set_prereserved_sandbox_size(system_info.prereserved_sandbox_size); 105 listener.set_prereserved_sandbox_size(system_info.prereserved_sandbox_size);
69 listener.set_number_of_cores(system_info.number_of_cores); 106 listener.set_number_of_cores(system_info.number_of_cores);
70 listener.Listen(); 107 listener.Listen();
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 base::TerminationStatus status; 216 base::TerminationStatus status;
180 if (known_dead) 217 if (known_dead)
181 status = base::GetKnownDeadTerminationStatus(child_to_wait, &exit_code); 218 status = base::GetKnownDeadTerminationStatus(child_to_wait, &exit_code);
182 else 219 else
183 status = base::GetTerminationStatus(child_to_wait, &exit_code); 220 status = base::GetTerminationStatus(child_to_wait, &exit_code);
184 output_pickle->WriteInt(static_cast<int>(status)); 221 output_pickle->WriteInt(static_cast<int>(status));
185 output_pickle->WriteInt(exit_code); 222 output_pickle->WriteInt(exit_code);
186 return true; 223 return true;
187 } 224 }
188 225
189 // This is a poor man's check on whether we are sandboxed.
190 bool IsSandboxed() {
191 int proc_fd = open("/proc/self/exe", O_RDONLY);
192 if (proc_fd >= 0) {
193 close(proc_fd);
194 return false;
195 }
196 return true;
197 }
198
199 // Honor a command |command_type|. Eventual command parameters are 226 // Honor a command |command_type|. Eventual command parameters are
200 // available in |input_iter| and eventual file descriptors attached to 227 // available in |input_iter| and eventual file descriptors attached to
201 // the command are in |attached_fds|. 228 // the command are in |attached_fds|.
202 // Reply to the command on |reply_fds|. 229 // Reply to the command on |reply_fds|.
203 bool HonorRequestAndReply(int reply_fd, 230 bool HonorRequestAndReply(int reply_fd,
204 int command_type, 231 int command_type,
205 const std::vector<int>& attached_fds, 232 const std::vector<int>& attached_fds,
206 const NaClLoaderSystemInfo& system_info, 233 const NaClLoaderSystemInfo& system_info,
207 PickleIterator* input_iter) { 234 PickleIterator* input_iter) {
208 Pickle write_pickle; 235 Pickle write_pickle;
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 // Now handle requests from the Zygote. 422 // Now handle requests from the Zygote.
396 while (true) { 423 while (true) {
397 bool request_handled = HandleZygoteRequest(kNaClZygoteDescriptor, 424 bool request_handled = HandleZygoteRequest(kNaClZygoteDescriptor,
398 system_info); 425 system_info);
399 // Do not turn this into a CHECK() without thinking about robustness 426 // Do not turn this into a CHECK() without thinking about robustness
400 // against malicious IPC requests. 427 // against malicious IPC requests.
401 DCHECK(request_handled); 428 DCHECK(request_handled);
402 } 429 }
403 NOTREACHED(); 430 NOTREACHED();
404 } 431 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698