OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "sandbox_impl.h" | 5 #include "sandbox_impl.h" |
6 | 6 |
7 #include "library.h" | 7 #include "library.h" |
8 #include "syscall_entrypoint.h" | 8 #include "syscall_entrypoint.h" |
9 #include "system_call_table.h" | 9 #include "system_call_table.h" |
10 | 10 |
11 namespace playground { | 11 namespace playground { |
12 | 12 |
13 // Global variables | 13 // Global variables |
14 int Sandbox::proc_self_ = -1; | |
14 int Sandbox::proc_self_maps_ = -1; | 15 int Sandbox::proc_self_maps_ = -1; |
15 enum Sandbox::SandboxStatus Sandbox::status_ = STATUS_UNKNOWN; | 16 enum Sandbox::SandboxStatus Sandbox::status_ = STATUS_UNKNOWN; |
16 int Sandbox::pid_; | 17 int Sandbox::pid_; |
17 int Sandbox::processFdPub_; | 18 int Sandbox::processFdPub_; |
18 int Sandbox::cloneFdPub_ | 19 int Sandbox::cloneFdPub_ |
19 // This is necessary to locate the symbol from assembly code on | 20 // This is necessary to locate the symbol from assembly code on |
20 // x86-64 (with %rip-relative addressing) in order for this to work | 21 // x86-64 (with %rip-relative addressing) in order for this to work |
21 // in relocatable code (a .so or a PIE). On i386 this is not | 22 // in relocatable code (a .so or a PIE). On i386 this is not |
22 // necessary but it does not hurt. | 23 // necessary but it does not hurt. |
23 __attribute__((visibility("internal"))); | 24 __attribute__((visibility("internal"))); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
210 return 0; | 211 return 0; |
211 case 0: { | 212 case 0: { |
212 int devnull = sys.open("/dev/null", O_RDWR, 0); | 213 int devnull = sys.open("/dev/null", O_RDWR, 0); |
213 if (devnull >= 0) { | 214 if (devnull >= 0) { |
214 sys.dup2(devnull, 0); | 215 sys.dup2(devnull, 0); |
215 sys.dup2(devnull, 1); | 216 sys.dup2(devnull, 1); |
216 sys.dup2(devnull, 2); | 217 sys.dup2(devnull, 2); |
217 sys.close(devnull); | 218 sys.close(devnull); |
218 } | 219 } |
219 if (proc_fd >= 0) { | 220 if (proc_fd >= 0) { |
220 setProcSelfMaps(sys.openat(proc_fd, "self/maps", O_RDONLY, 0)); | 221 setProcSelf(sys.openat(proc_fd, "self", O_RDONLY|O_DIRECTORY, 0)); |
221 } | 222 } |
222 startSandbox(); | 223 startSandbox(); |
223 write(sys, fds[1], "", 1); | 224 write(sys, fds[1], "", 1); |
224 | 225 |
225 // Try to tell the trusted thread to shut down the entire process in an | 226 // Try to tell the trusted thread to shut down the entire process in an |
226 // orderly fashion | 227 // orderly fashion |
227 defaultSystemCallHandler(__NR_exit_group, 0, 0, 0, 0, 0, 0); | 228 defaultSystemCallHandler(__NR_exit_group, 0, 0, 0, 0, 0, 0); |
228 | 229 |
229 // If that did not work (e.g. because the kernel does not know about the | 230 // If that did not work (e.g. because the kernel does not know about the |
230 // exit_group() system call), make a direct _exit() system call instead. | 231 // exit_group() system call), make a direct _exit() system call instead. |
(...skipping 12 matching lines...) Expand all Loading... | |
243 } else { | 244 } else { |
244 status_ = STATUS_AVAILABLE; | 245 status_ = STATUS_AVAILABLE; |
245 } | 246 } |
246 int rc; | 247 int rc; |
247 (void)NOINTR_SYS(sys.waitpid(pid, &rc, 0)); | 248 (void)NOINTR_SYS(sys.waitpid(pid, &rc, 0)); |
248 (void)NOINTR_SYS(sys.close(fds[0])); | 249 (void)NOINTR_SYS(sys.close(fds[0])); |
249 return status_ != STATUS_UNSUPPORTED; | 250 return status_ != STATUS_UNSUPPORTED; |
250 } | 251 } |
251 } | 252 } |
252 | 253 |
253 void Sandbox::setProcSelfMaps(int proc_self_maps) { | 254 void Sandbox::setProcSelf(int proc_self) { |
Mark Seaborn
2012/04/27 23:07:38
The smallest change would be to make setProcSelf()
Markus (顧孟勤)
2012/04/28 01:15:43
That actually breaks the existing API in a subtle
| |
254 proc_self_maps_ = proc_self_maps; | 255 proc_self_ = proc_self; |
255 } | 256 } |
256 | 257 |
257 void Sandbox::startSandbox() { | 258 void Sandbox::startSandbox() { |
258 if (status_ == STATUS_UNSUPPORTED) { | 259 if (status_ == STATUS_UNSUPPORTED) { |
259 die("The seccomp sandbox is not supported on this computer"); | 260 die("The seccomp sandbox is not supported on this computer"); |
260 } else if (status_ == STATUS_ENABLED) { | 261 } else if (status_ == STATUS_ENABLED) { |
261 return; | 262 return; |
262 } | 263 } |
263 | 264 |
264 SysCalls sys; | 265 SysCalls sys; |
266 if (proc_self_ >= 0) { | |
267 proc_self_maps_ = sys.openat(proc_self_, "maps", O_RDONLY, 0); | |
268 NOINTR_SYS(sys.close(proc_self_)); | |
jln (very slow on Chromium)
2012/04/27 23:08:20
Should we check for close() errors here ? Since th
| |
269 proc_self_ = -1; | |
270 } | |
265 if (proc_self_maps_ < 0) { | 271 if (proc_self_maps_ < 0) { |
266 proc_self_maps_ = sys.open("/proc/self/maps", O_RDONLY, 0); | 272 proc_self_maps_ = sys.open("/proc/self/maps", O_RDONLY, 0); |
267 if (proc_self_maps_ < 0) { | 273 if (proc_self_maps_ < 0) { |
268 die("Cannot access \"/proc/self/maps\""); | 274 die("Cannot access \"/proc/self/maps\""); |
269 } | 275 } |
270 } | 276 } |
271 | 277 |
272 // The pid is unchanged for the entire program, so we can retrieve it once | 278 // The pid is unchanged for the entire program, so we can retrieve it once |
273 // and store it in a global variable. | 279 // and store it in a global variable. |
274 pid_ = sys.getpid(); | 280 pid_ = sys.getpid(); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
378 } entrypoint; | 384 } entrypoint; |
379 *entrypoint.get_syscall_entrypoint() = syscallEntryPointNoFrame; | 385 *entrypoint.get_syscall_entrypoint() = syscallEntryPointNoFrame; |
380 | 386 |
381 // We can no longer check for sandboxing support at this point, but we also | 387 // We can no longer check for sandboxing support at this point, but we also |
382 // know for a fact that it is available (as we just turned it on). So update | 388 // know for a fact that it is available (as we just turned it on). So update |
383 // the status to reflect this information. | 389 // the status to reflect this information. |
384 status_ = STATUS_ENABLED; | 390 status_ = STATUS_ENABLED; |
385 } | 391 } |
386 | 392 |
387 } // namespace | 393 } // namespace |
OLD | NEW |