summaryrefslogtreecommitdiffstats
path: root/sandbox
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox')
-rw-r--r--sandbox/linux/seccomp-bpf/sandbox_bpf.cc63
-rw-r--r--sandbox/linux/seccomp-bpf/sandbox_bpf.h21
2 files changed, 19 insertions, 65 deletions
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
index 5f7d028..56931d1 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
@@ -31,10 +31,6 @@ bool Sandbox::kernelSupportSeccompBPF(int proc_fd) {
sigprocmask(SIG_BLOCK, &newMask, &oldMask)) {
die("sigprocmask() failed");
}
- int fds[2];
- if (pipe2(fds, O_NONBLOCK|O_CLOEXEC)) {
- die("pipe() failed");
- }
pid_t pid = fork();
if (pid < 0) {
@@ -52,28 +48,18 @@ bool Sandbox::kernelSupportSeccompBPF(int proc_fd) {
if (!pid) {
// Test a very simple sandbox policy to verify that we can
// successfully turn on sandboxing.
- dryRun_ = true;
- if (HANDLE_EINTR(close(fds[0])) ||
- dup2(fds[1], 2) != 2 ||
- HANDLE_EINTR(close(fds[1]))) {
- static const char msg[] = "Failed to set up stderr\n";
- (void)HANDLE_EINTR(write(fds[1], msg, sizeof(msg)-1));
- } else {
- evaluators_.clear();
- setSandboxPolicy(probeEvaluator, NULL);
- setProcFd(proc_fd);
- startSandbox();
- if (syscall(__NR_getpid) < 0 && errno == EPERM) {
- syscall(__NR_exit_group, (intptr_t)100);
- }
+ suppressLogging_ = true;
+ evaluators_.clear();
+ setSandboxPolicy(probeEvaluator, NULL);
+ setProcFd(proc_fd);
+ startSandbox();
+ if (syscall(__NR_getpid) < 0 && errno == EPERM) {
+ syscall(__NR_exit_group, (intptr_t)100);
}
die(NULL);
}
// In the parent process
- if (HANDLE_EINTR(close(fds[1]))) {
- die("close() failed");
- }
if (sigprocmask(SIG_SETMASK, &oldMask, NULL)) {
die("sigprocmask() failed");
}
@@ -81,29 +67,7 @@ bool Sandbox::kernelSupportSeccompBPF(int proc_fd) {
if (HANDLE_EINTR(waitpid(pid, &status, 0)) != pid) {
die("waitpid() failed unexpectedly");
}
- bool rc = WIFEXITED(status) && WEXITSTATUS(status) == 100;
-
- // If we fail to support sandboxing, there might be an additional
- // error message. If so, this was an entirely unexpected and fatal
- // failure. We should report the failure and somebody most fix
- // things. This is probably a security-critical bug in the sandboxing
- // code.
- if (!rc) {
- char buf[4096];
- ssize_t len = HANDLE_EINTR(read(fds[0], buf, sizeof(buf) - 1));
- if (len > 0) {
- while (len > 1 && buf[len-1] == '\n') {
- --len;
- }
- buf[len] = '\000';
- die(buf);
- }
- }
- if (HANDLE_EINTR(close(fds[0]))) {
- die("close() failed");
- }
-
- return rc;
+ return WIFEXITED(status) && WEXITSTATUS(status) == 100;
}
Sandbox::SandboxStatus Sandbox::supportsSeccompSandbox(int proc_fd) {
@@ -348,12 +312,9 @@ void Sandbox::installFilter() {
delete program;
// Install BPF filter program
- if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
- die(dryRun_ ? NULL : "Kernel refuses to enable no-new-privs");
- } else {
- if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
- die(dryRun_ ? NULL : "Kernel refuses to turn on BPF filters");
- }
+ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) ||
+ prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
+ goto filter_failed;
}
return;
@@ -390,7 +351,7 @@ void Sandbox::sigSys(int nr, siginfo_t *info, void *void_context) {
}
-bool Sandbox::dryRun_ = false;
+bool Sandbox::suppressLogging_ = false;
Sandbox::SandboxStatus Sandbox::status_ = STATUS_UNKNOWN;
int Sandbox::proc_fd_ = -1;
std::vector<std::pair<Sandbox::EvaluateSyscall,
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.h b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
index 9a50798..82e4656 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.h
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
@@ -190,9 +190,12 @@ class Sandbox {
protected:
// Print an error message and terminate the program. Used for fatal errors.
static void die(const char *msg) __attribute__((noreturn)) {
- if (msg) {
-#ifndef SECCOMP_BPF_STANDALONE
- if (!dryRun_) {
+ if (!suppressLogging_) {
+ if (msg) {
+#ifdef SECCOMP_BPF_STANDALONE
+ HANDLE_EINTR(write(2, msg, strlen(msg)));
+ HANDLE_EINTR(write(2, "\n", 1));
+#else
// LOG(FATAL) is not neccessarily async-signal safe. It would be
// better to always use the code for the SECCOMP_BPF_STANDALONE case.
// But that prevents the logging and reporting infrastructure from
@@ -201,17 +204,7 @@ class Sandbox {
// LOG(FATAL). In the long run, we probably want to rewrite this code
// to be async-signal safe.
LOG(FATAL) << msg;
- } else
#endif
- {
- // If there is no logging infrastructure in place, we just write error
- // messages to stderr.
- // We also write to stderr, if we are called in a child process from
- // supportsSeccompSandbox(). This makes sure we can actually do the
- // correct logging from the parent process, which is more likely to
- // have access to logging infrastructure.
- HANDLE_EINTR(write(2, msg, strlen(msg)));
- HANDLE_EINTR(write(2, "\n", 1));
}
}
for (;;) {
@@ -240,7 +233,7 @@ class Sandbox {
static void installFilter();
static void sigSys(int nr, siginfo_t *info, void *void_context);
- static bool dryRun_;
+ static bool suppressLogging_;
static SandboxStatus status_;
static int proc_fd_;
static std::vector<std::pair<EvaluateSyscall,