Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <dirent.h> | 5 #include <dirent.h> |
| 6 #include <fcntl.h> | 6 #include <fcntl.h> |
| 7 #include <sys/resource.h> | 7 #include <sys/resource.h> |
| 8 #include <sys/stat.h> | 8 #include <sys/stat.h> |
| 9 #include <sys/time.h> | 9 #include <sys/time.h> |
| 10 #include <sys/types.h> | 10 #include <sys/types.h> |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 } | 72 } |
| 73 | 73 |
| 74 bool IsRunningTSAN() { | 74 bool IsRunningTSAN() { |
| 75 #if defined(THREAD_SANITIZER) | 75 #if defined(THREAD_SANITIZER) |
| 76 return true; | 76 return true; |
| 77 #else | 77 #else |
| 78 return false; | 78 return false; |
| 79 #endif | 79 #endif |
| 80 } | 80 } |
| 81 | 81 |
| 82 bool IsChromeOS() { | |
| 83 #if defined(OS_CHROMEOS) | |
| 84 return true; | |
| 85 #else | |
| 86 return false; | |
| 87 #endif | |
| 88 } | |
| 89 | |
| 82 // Try to open /proc/self/task/ with the help of |proc_fd|. |proc_fd| can be | 90 // Try to open /proc/self/task/ with the help of |proc_fd|. |proc_fd| can be |
| 83 // -1. Will return -1 on error and set errno like open(2). | 91 // -1. Will return -1 on error and set errno like open(2). |
| 84 int OpenProcTaskFd(int proc_fd) { | 92 int OpenProcTaskFd(int proc_fd) { |
| 85 int proc_self_task = -1; | 93 int proc_self_task = -1; |
| 86 if (proc_fd >= 0) { | 94 if (proc_fd >= 0) { |
| 87 // If a handle to /proc is available, use it. This allows to bypass file | 95 // If a handle to /proc is available, use it. This allows to bypass file |
| 88 // system restrictions. | 96 // system restrictions. |
| 89 proc_self_task = openat(proc_fd, "self/task/", O_RDONLY | O_DIRECTORY); | 97 proc_self_task = openat(proc_fd, "self/task/", O_RDONLY | O_DIRECTORY); |
| 90 } else { | 98 } else { |
| 91 // Otherwise, make an attempt to access the file system directly. | 99 // Otherwise, make an attempt to access the file system directly. |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 if (seccomp_bpf_supported()) | 237 if (seccomp_bpf_supported()) |
| 230 seccomp_bpf_started_ = SandboxSeccompBPF::StartSandbox(process_type); | 238 seccomp_bpf_started_ = SandboxSeccompBPF::StartSandbox(process_type); |
| 231 | 239 |
| 232 if (seccomp_bpf_started_) | 240 if (seccomp_bpf_started_) |
| 233 LogSandboxStarted("seccomp-bpf"); | 241 LogSandboxStarted("seccomp-bpf"); |
| 234 | 242 |
| 235 return seccomp_bpf_started_; | 243 return seccomp_bpf_started_; |
| 236 } | 244 } |
| 237 | 245 |
| 238 bool LinuxSandbox::InitializeSandboxImpl() { | 246 bool LinuxSandbox::InitializeSandboxImpl() { |
| 247 CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
| 239 const std::string process_type = | 248 const std::string process_type = |
| 240 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 249 command_line->GetSwitchValueASCII(switches::kProcessType); |
| 241 switches::kProcessType); | |
| 242 | 250 |
| 243 // We need to make absolutely sure that our sandbox is "sealed" before | 251 // We need to make absolutely sure that our sandbox is "sealed" before |
| 244 // returning. | 252 // returning. |
| 245 // Unretained() since the current object is a Singleton. | 253 // Unretained() since the current object is a Singleton. |
| 246 base::ScopedClosureRunner sandbox_sealer( | 254 base::ScopedClosureRunner sandbox_sealer( |
| 247 base::Bind(&LinuxSandbox::SealSandbox, base::Unretained(this))); | 255 base::Bind(&LinuxSandbox::SealSandbox, base::Unretained(this))); |
| 248 // Make sure that this function enables sandboxes as promised by GetStatus(). | 256 // Make sure that this function enables sandboxes as promised by GetStatus(). |
| 249 // Unretained() since the current object is a Singleton. | 257 // Unretained() since the current object is a Singleton. |
| 250 base::ScopedClosureRunner sandbox_promise_keeper( | 258 base::ScopedClosureRunner sandbox_promise_keeper( |
| 251 base::Bind(&LinuxSandbox::CheckForBrokenPromises, | 259 base::Bind(&LinuxSandbox::CheckForBrokenPromises, |
| 252 base::Unretained(this), | 260 base::Unretained(this), |
| 253 process_type)); | 261 process_type)); |
| 254 | 262 |
| 255 // No matter what, it's always an error to call InitializeSandbox() after | 263 // No matter what, it's always an error to call InitializeSandbox() after |
| 256 // threads have been created. | 264 // threads have been created. |
| 257 if (!IsSingleThreaded()) { | 265 if (!IsSingleThreaded()) { |
| 258 std::string error_message = "InitializeSandbox() called with multiple " | 266 std::string error_message = "InitializeSandbox() called with multiple " |
| 259 "threads in process " + process_type; | 267 "threads in process " + process_type; |
| 260 // TSAN starts a helper thread. So we don't start the sandbox and don't | 268 // TSAN starts a helper thread. So we don't start the sandbox and don't |
| 261 // even report an error about it. | 269 // even report an error about it. |
| 262 if (IsRunningTSAN()) | 270 if (IsRunningTSAN()) |
| 263 return false; | 271 return false; |
| 264 // The GPU process is allowed to call InitializeSandbox() with threads for | 272 |
| 265 // now, because it loads third-party libraries. | 273 bool sandbox_failure_nonfatal = false; |
|
jln (very slow on Chromium)
2014/03/06 23:02:30
So, on non regular Linux, this will crash, no?
ni
Jorge Lucangeli Obes
2014/03/07 00:29:44
Done. Was halfway done changing the name of the fl
| |
| 266 if (process_type != switches::kGpuProcess) | 274 |
| 275 // On Chrome OS, the GPU process is allowed to call InitializeSandbox() | |
| 276 // with threads, but only if '--gpu-sandbox-failures-nonfatal' is passed. | |
| 277 if (IsChromeOS()) { | |
| 278 sandbox_failure_nonfatal = | |
| 279 process_type == switches::kGpuProcess && | |
| 280 command_line->HasSwitch(switches::kGpuSandboxFailuresNonfatal); | |
| 281 } | |
| 282 | |
| 283 if (!sandbox_failure_nonfatal) | |
| 267 CHECK(false) << error_message; | 284 CHECK(false) << error_message; |
|
jln (very slow on Chromium)
2014/03/06 23:02:30
LOG(FATAL) instead?
Jorge Lucangeli Obes
2014/03/07 00:29:44
Done.
| |
| 285 | |
| 268 LOG(ERROR) << error_message; | 286 LOG(ERROR) << error_message; |
| 269 return false; | 287 return false; |
| 270 } | 288 } |
| 271 | 289 |
| 272 // Only one thread is running, pre-initialize if not already done. | 290 // Only one thread is running, pre-initialize if not already done. |
| 273 if (!pre_initialized_) | 291 if (!pre_initialized_) |
| 274 PreinitializeSandbox(); | 292 PreinitializeSandbox(); |
| 275 | 293 |
| 276 DCHECK(!HasOpenDirectories()) << | 294 DCHECK(!HasOpenDirectories()) << |
| 277 "InitializeSandbox() called after unexpected directories have been " << | 295 "InitializeSandbox() called after unexpected directories have been " << |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 void LinuxSandbox::StopThreadAndEnsureNotCounted(base::Thread* thread) const { | 384 void LinuxSandbox::StopThreadAndEnsureNotCounted(base::Thread* thread) const { |
| 367 DCHECK(thread); | 385 DCHECK(thread); |
| 368 int proc_self_task = OpenProcTaskFd(proc_fd_); | 386 int proc_self_task = OpenProcTaskFd(proc_fd_); |
| 369 PCHECK(proc_self_task >= 0); | 387 PCHECK(proc_self_task >= 0); |
| 370 SafeScopedFD task_closer(&proc_self_task); | 388 SafeScopedFD task_closer(&proc_self_task); |
| 371 CHECK( | 389 CHECK( |
| 372 sandbox::ThreadHelpers::StopThreadAndWatchProcFS(proc_self_task, thread)); | 390 sandbox::ThreadHelpers::StopThreadAndWatchProcFS(proc_self_task, thread)); |
| 373 } | 391 } |
| 374 | 392 |
| 375 } // namespace content | 393 } // namespace content |
| OLD | NEW |