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

Unified Diff: sandbox/linux/seccomp-bpf/sandbox_bpf.cc

Issue 733303004: Linux sandbox: change API to start the sandbox (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address nits from Jorge. Created 6 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf.h ('k') | sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sandbox/linux/seccomp-bpf/sandbox_bpf.cc
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
index 43c9af6f339be05c5a841da22474b3449144ab17..189485062b27ff2cef7b9ad8ee623ca3f93e1601 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
@@ -42,6 +42,7 @@
#include "sandbox/linux/seccomp-bpf/verifier.h"
#include "sandbox/linux/services/linux_syscalls.h"
#include "sandbox/linux/services/syscall_wrappers.h"
+#include "sandbox/linux/services/thread_helpers.h"
using sandbox::bpf_dsl::Allow;
using sandbox::bpf_dsl::Error;
@@ -122,33 +123,19 @@ void TryVsyscallProcess(void) {
}
}
-bool IsSingleThreaded(int proc_fd) {
- if (proc_fd < 0) {
- // Cannot determine whether program is single-threaded. Hope for
- // the best...
- return true;
- }
-
- struct stat sb;
- int task = -1;
- if ((task = openat(proc_fd, "self/task", O_RDONLY | O_DIRECTORY)) < 0 ||
- fstat(task, &sb) != 0 || sb.st_nlink != 3 || IGNORE_EINTR(close(task))) {
- if (task >= 0) {
- if (IGNORE_EINTR(close(task))) {
- }
- }
- return false;
- }
- return true;
+bool IsSingleThreaded(int proc_task_fd) {
+ return ThreadHelpers::IsSingleThreaded(proc_task_fd);
}
} // namespace
SandboxBPF::SandboxBPF()
- : quiet_(false), proc_fd_(-1), sandbox_has_started_(false), policy_() {
+ : quiet_(false), proc_task_fd_(-1), sandbox_has_started_(false), policy_() {
}
SandboxBPF::~SandboxBPF() {
+ if (proc_task_fd_ != -1)
+ IGNORE_EINTR(close(proc_task_fd_));
}
bool SandboxBPF::IsValidSyscallNumber(int sysnum) {
@@ -175,7 +162,7 @@ bool SandboxBPF::RunFunctionInPolicy(void (*code_in_sandbox)(),
// This code is using fork() and should only ever run single-threaded.
// Most of the code below is "async-signal-safe" and only minor changes
// would be needed to support threads.
- DCHECK(IsSingleThreaded(proc_fd_));
+ DCHECK(IsSingleThreaded(proc_task_fd_));
pid_t pid = fork();
if (pid < 0) {
// Die if we cannot fork(). We would probably fail a little later
@@ -282,58 +269,28 @@ bool SandboxBPF::KernelSupportSeccompBPF() {
}
// static
-SandboxBPF::SandboxStatus SandboxBPF::SupportsSeccompSandbox(int proc_fd) {
- // It the sandbox is currently active, we clearly must have support for
- // sandboxing.
- if (status_ == STATUS_ENABLED) {
- return status_;
- }
-
- // Even if the sandbox was previously available, something might have
- // changed in our run-time environment. Check one more time.
- if (status_ == STATUS_AVAILABLE) {
- if (!IsSingleThreaded(proc_fd)) {
- status_ = STATUS_UNAVAILABLE;
- }
- return status_;
- }
-
- if (status_ == STATUS_UNAVAILABLE && IsSingleThreaded(proc_fd)) {
- // All state transitions resulting in STATUS_UNAVAILABLE are immediately
- // preceded by STATUS_AVAILABLE. Furthermore, these transitions all
- // happen, if and only if they are triggered by the process being multi-
- // threaded.
- // In other words, if a single-threaded process is currently in the
- // STATUS_UNAVAILABLE state, it is safe to assume that sandboxing is
- // actually available.
- status_ = STATUS_AVAILABLE;
+SandboxBPF::SandboxStatus SandboxBPF::SupportsSeccompSandbox() {
+ if (status_ != STATUS_UNKNOWN) {
return status_;
}
// If we have not previously checked for availability of the sandbox or if
// we otherwise don't believe to have a good cached value, we have to
// perform a thorough check now.
- if (status_ == STATUS_UNKNOWN) {
- // We create our own private copy of a "Sandbox" object. This ensures that
- // the object does not have any policies configured, that might interfere
- // with the tests done by "KernelSupportSeccompBPF()".
- SandboxBPF sandbox;
-
- // By setting "quiet_ = true" we suppress messages for expected and benign
- // failures (e.g. if the current kernel lacks support for BPF filters).
- sandbox.quiet_ = true;
- sandbox.set_proc_fd(proc_fd);
- status_ = sandbox.KernelSupportSeccompBPF() ? STATUS_AVAILABLE
- : STATUS_UNSUPPORTED;
-
- // As we are performing our tests from a child process, the run-time
- // environment that is visible to the sandbox is always guaranteed to be
- // single-threaded. Let's check here whether the caller is single-
- // threaded. Otherwise, we mark the sandbox as temporarily unavailable.
- if (status_ == STATUS_AVAILABLE && !IsSingleThreaded(proc_fd)) {
- status_ = STATUS_UNAVAILABLE;
- }
- }
+
+ // We create our own private copy of a "Sandbox" object. This ensures that
+ // the object does not have any policies configured, that might interfere
+ // with the tests done by "KernelSupportSeccompBPF()".
+ SandboxBPF sandbox;
+
+ // By setting "quiet_ = true" we suppress messages for expected and benign
+ // failures (e.g. if the current kernel lacks support for BPF filters).
+ // TODO(jln): use kernel API to check for seccomp support now that things
+ // have stabilized.
+ sandbox.quiet_ = true;
+ status_ =
+ sandbox.KernelSupportSeccompBPF() ? STATUS_AVAILABLE : STATUS_UNSUPPORTED;
+
return status_;
}
@@ -355,7 +312,9 @@ SandboxBPF::SupportsSeccompThreadFilterSynchronization() {
}
}
-void SandboxBPF::set_proc_fd(int proc_fd) { proc_fd_ = proc_fd; }
+void SandboxBPF::set_proc_task_fd(int proc_task_fd) {
+ proc_task_fd_ = proc_task_fd;
+}
bool SandboxBPF::StartSandbox(SandboxThreadState thread_state) {
CHECK(thread_state == PROCESS_SINGLE_THREADED ||
@@ -372,24 +331,17 @@ bool SandboxBPF::StartSandbox(SandboxThreadState thread_state) {
"object instead.");
return false;
}
- if (proc_fd_ < 0) {
- proc_fd_ = open("/proc", O_RDONLY | O_DIRECTORY);
- }
- if (proc_fd_ < 0) {
- // For now, continue in degraded mode, if we can't access /proc.
- // In the future, we might want to tighten this requirement.
- }
bool supports_tsync =
SupportsSeccompThreadFilterSynchronization() == STATUS_AVAILABLE;
if (thread_state == PROCESS_SINGLE_THREADED) {
- if (!IsSingleThreaded(proc_fd_)) {
+ if (!IsSingleThreaded(proc_task_fd_)) {
SANDBOX_DIE("Cannot start sandbox; process is already multi-threaded");
return false;
}
} else if (thread_state == PROCESS_MULTI_THREADED) {
- if (IsSingleThreaded(proc_fd_)) {
+ if (IsSingleThreaded(proc_task_fd_)) {
SANDBOX_DIE("Cannot start sandbox; "
"process may be single-threaded when reported as not");
return false;
@@ -404,12 +356,12 @@ bool SandboxBPF::StartSandbox(SandboxThreadState thread_state) {
// We no longer need access to any files in /proc. We want to do this
// before installing the filters, just in case that our policy denies
// close().
- if (proc_fd_ >= 0) {
- if (IGNORE_EINTR(close(proc_fd_))) {
+ if (proc_task_fd_ >= 0) {
+ if (IGNORE_EINTR(close(proc_task_fd_))) {
SANDBOX_DIE("Failed to close file descriptor for /proc");
return false;
}
- proc_fd_ = -1;
+ proc_task_fd_ = -1;
}
// Install the filters.
« no previous file with comments | « sandbox/linux/seccomp-bpf/sandbox_bpf.h ('k') | sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698