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

Side by Side Diff: components/nacl/loader/sandbox_linux/nacl_sandbox_linux.cc

Issue 733303004: Linux sandbox: change API to start the sandbox (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rewrap comment. Created 6 years 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 #include "components/nacl/loader/sandbox_linux/nacl_sandbox_linux.h" 5 #include "components/nacl/loader/sandbox_linux/nacl_sandbox_linux.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <sys/stat.h> 9 #include <sys/stat.h>
10 #include <sys/types.h> 10 #include <sys/types.h>
11 #include <unistd.h> 11 #include <unistd.h>
12 12
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/callback.h" 14 #include "base/callback.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/compiler_specific.h" 16 #include "base/compiler_specific.h"
17 #include "base/files/scoped_file.h"
17 #include "base/logging.h" 18 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h" 19 #include "base/memory/scoped_ptr.h"
19 #include "base/posix/eintr_wrapper.h" 20 #include "base/posix/eintr_wrapper.h"
20 #include "build/build_config.h" 21 #include "build/build_config.h"
21 #include "components/nacl/common/nacl_switches.h" 22 #include "components/nacl/common/nacl_switches.h"
22 #include "components/nacl/loader/nonsfi/nonsfi_sandbox.h" 23 #include "components/nacl/loader/nonsfi/nonsfi_sandbox.h"
23 #include "components/nacl/loader/sandbox_linux/nacl_bpf_sandbox_linux.h" 24 #include "components/nacl/loader/sandbox_linux/nacl_bpf_sandbox_linux.h"
25 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
24 #include "sandbox/linux/services/credentials.h" 26 #include "sandbox/linux/services/credentials.h"
25 #include "sandbox/linux/services/thread_helpers.h" 27 #include "sandbox/linux/services/thread_helpers.h"
26 #include "sandbox/linux/suid/client/setuid_sandbox_client.h" 28 #include "sandbox/linux/suid/client/setuid_sandbox_client.h"
27 29
28 namespace nacl { 30 namespace nacl {
29 31
30 namespace { 32 namespace {
31 33
32 // This is a poor man's check on whether we are sandboxed. 34 // This is a poor man's check on whether we are sandboxed.
33 bool IsSandboxed() { 35 bool IsSandboxed() {
34 int proc_fd = open("/proc/self/exe", O_RDONLY); 36 int proc_fd = open("/proc/self/exe", O_RDONLY);
35 if (proc_fd >= 0) { 37 if (proc_fd >= 0) {
36 PCHECK(0 == IGNORE_EINTR(close(proc_fd))); 38 PCHECK(0 == IGNORE_EINTR(close(proc_fd)));
37 return false; 39 return false;
38 } 40 }
39 return true; 41 return true;
40 } 42 }
41 43
44 // Open a new file descriptor to /proc/self/task/ by using
45 // |proc_fd|.
46 base::ScopedFD GetProcSelfTask(int proc_fd) {
47 base::ScopedFD proc_self_task(HANDLE_EINTR(
48 openat(proc_fd, "self/task/", O_RDONLY | O_DIRECTORY | O_CLOEXEC)));
49 PCHECK(proc_self_task.is_valid());
50 return proc_self_task.Pass();
51 }
52
42 } // namespace 53 } // namespace
43 54
44 NaClSandbox::NaClSandbox() 55 NaClSandbox::NaClSandbox()
45 : layer_one_enabled_(false), 56 : layer_one_enabled_(false),
46 layer_one_sealed_(false), 57 layer_one_sealed_(false),
47 layer_two_enabled_(false), 58 layer_two_enabled_(false),
48 layer_two_is_nonsfi_(false), 59 layer_two_is_nonsfi_(false),
49 proc_fd_(-1), 60 proc_fd_(-1),
50 setuid_sandbox_client_(sandbox::SetuidSandboxClient::Create()) { 61 setuid_sandbox_client_(sandbox::SetuidSandboxClient::Create()) {
51 proc_fd_.reset( 62 proc_fd_.reset(
52 HANDLE_EINTR(open("/proc", O_DIRECTORY | O_RDONLY | O_CLOEXEC))); 63 HANDLE_EINTR(open("/proc", O_DIRECTORY | O_RDONLY | O_CLOEXEC)));
53 PCHECK(proc_fd_.is_valid()); 64 PCHECK(proc_fd_.is_valid());
65 // Determine if the kernel supports seccomp-bpf and let it cache the
66 // result. This must be done before any sandbox is engaged.
67 sandbox::SandboxBPF::SupportsSeccompSandbox();
54 } 68 }
55 69
56 NaClSandbox::~NaClSandbox() { 70 NaClSandbox::~NaClSandbox() {
57 } 71 }
58 72
59 bool NaClSandbox::IsSingleThreaded() { 73 bool NaClSandbox::IsSingleThreaded() {
60 CHECK(proc_fd_.is_valid()); 74 CHECK(proc_fd_.is_valid());
61 base::ScopedFD proc_self_task(HANDLE_EINTR(openat( 75 base::ScopedFD proc_self_task(GetProcSelfTask(proc_fd_.get()));
62 proc_fd_.get(), "self/task/", O_RDONLY | O_DIRECTORY | O_CLOEXEC)));
63 PCHECK(proc_self_task.is_valid());
64 return sandbox::ThreadHelpers::IsSingleThreaded(proc_self_task.get()); 76 return sandbox::ThreadHelpers::IsSingleThreaded(proc_self_task.get());
65 } 77 }
66 78
67 bool NaClSandbox::HasOpenDirectory() { 79 bool NaClSandbox::HasOpenDirectory() {
68 CHECK(proc_fd_.is_valid()); 80 CHECK(proc_fd_.is_valid());
69 sandbox::Credentials credentials; 81 sandbox::Credentials credentials;
70 return credentials.HasOpenDirectory(proc_fd_.get()); 82 return credentials.HasOpenDirectory(proc_fd_.get());
71 } 83 }
72 84
73 void NaClSandbox::InitializeLayerOneSandbox() { 85 void NaClSandbox::InitializeLayerOneSandbox() {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 } 119 }
108 } 120 }
109 121
110 void NaClSandbox::InitializeLayerTwoSandbox(bool uses_nonsfi_mode) { 122 void NaClSandbox::InitializeLayerTwoSandbox(bool uses_nonsfi_mode) {
111 // seccomp-bpf only applies to the current thread, so it's critical to only 123 // seccomp-bpf only applies to the current thread, so it's critical to only
112 // have a single thread running here. 124 // have a single thread running here.
113 DCHECK(!layer_one_sealed_); 125 DCHECK(!layer_one_sealed_);
114 CHECK(IsSingleThreaded()); 126 CHECK(IsSingleThreaded());
115 CheckForExpectedNumberOfOpenFds(); 127 CheckForExpectedNumberOfOpenFds();
116 128
129 base::ScopedFD proc_self_task(GetProcSelfTask(proc_fd_.get()));
130
117 if (uses_nonsfi_mode) { 131 if (uses_nonsfi_mode) {
118 layer_two_enabled_ = nacl::nonsfi::InitializeBPFSandbox(); 132 layer_two_enabled_ =
133 nacl::nonsfi::InitializeBPFSandbox(proc_self_task.Pass());
119 layer_two_is_nonsfi_ = true; 134 layer_two_is_nonsfi_ = true;
120 } else { 135 } else {
121 layer_two_enabled_ = nacl::InitializeBPFSandbox(); 136 layer_two_enabled_ = nacl::InitializeBPFSandbox(proc_self_task.Pass());
122 } 137 }
123 } 138 }
124 139
125 void NaClSandbox::SealLayerOneSandbox() { 140 void NaClSandbox::SealLayerOneSandbox() {
126 if (!layer_two_enabled_) { 141 if (!layer_two_enabled_) {
127 // If nothing prevents us, check that there is no superfluous directory 142 // If nothing prevents us, check that there is no superfluous directory
128 // open. 143 // open.
129 CHECK(!HasOpenDirectory()); 144 CHECK(!HasOpenDirectory());
130 } 145 }
131 proc_fd_.reset(); 146 proc_fd_.reset();
(...skipping 24 matching lines...) Expand all
156 static const char kNoBpfMsg[] = 171 static const char kNoBpfMsg[] =
157 "The seccomp-bpf sandbox is not engaged for NaCl:"; 172 "The seccomp-bpf sandbox is not engaged for NaCl:";
158 if (can_be_no_sandbox) 173 if (can_be_no_sandbox)
159 LOG(ERROR) << kNoBpfMsg << kItIsDangerousMsg; 174 LOG(ERROR) << kNoBpfMsg << kItIsDangerousMsg;
160 else 175 else
161 LOG(FATAL) << kNoBpfMsg << kItIsNotAllowedMsg; 176 LOG(FATAL) << kNoBpfMsg << kItIsNotAllowedMsg;
162 } 177 }
163 } 178 }
164 179
165 } // namespace nacl 180 } // namespace nacl
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698