diff options
Diffstat (limited to 'sandbox')
-rw-r--r-- | sandbox/linux/seccomp-bpf/sandbox_bpf.cc | 63 | ||||
-rw-r--r-- | sandbox/linux/seccomp-bpf/sandbox_bpf.h | 21 |
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, |