diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-13 20:00:34 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-13 20:00:34 +0000 |
commit | b2182cd794ce68cc2b4dc3cae73a5f3a1a09b6e4 (patch) | |
tree | cd68b2a0ee642244da72b4f0d69200706065cea2 /sandbox | |
parent | 9b273b6e8eb5ee2e2eaca26fb4b637a0e0df1b96 (diff) | |
download | chromium_src-b2182cd794ce68cc2b4dc3cae73a5f3a1a09b6e4.zip chromium_src-b2182cd794ce68cc2b4dc3cae73a5f3a1a09b6e4.tar.gz chromium_src-b2182cd794ce68cc2b4dc3cae73a5f3a1a09b6e4.tar.bz2 |
Revert 141938 - Improve logging, if we fail due to an internal error when executing supportsSeccompSandbox(). Previously, we would just report that the sandbox is unavailable. That's undesirable behavior, because it would lead the caller to think that they should continue without the sandbox. A simple bug in the sandbox compiler could thus result in us inadvertently disabling sandboxing for all users -- without necessarily noticing this issue for a while.
BUG=130662
TEST=make && ./demo32 && ./demo64
Review URL: https://chromiumcodereview.appspot.com/10545100
TBR=markus@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10540145
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@141949 0039d316-1c4b-4281-b951-d872f2087c98
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, |