summaryrefslogtreecommitdiffstats
path: root/sandbox/linux
diff options
context:
space:
mode:
authormarkus@chromium.org <markus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-04 17:52:47 +0000
committermarkus@chromium.org <markus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-04 17:52:47 +0000
commite8c916abb296015f9b39c8684cb17be6023147e3 (patch)
tree0b3d60785570c412ae40f241891faf5221fca9e0 /sandbox/linux
parenta96ec6a0045c0b1926c9e4c553b67e42a43a430b (diff)
downloadchromium_src-e8c916abb296015f9b39c8684cb17be6023147e3.zip
chromium_src-e8c916abb296015f9b39c8684cb17be6023147e3.tar.gz
chromium_src-e8c916abb296015f9b39c8684cb17be6023147e3.tar.bz2
Only enable the seccomp sandbox, if the machine actually has kernel support for
this feature, and if no other obstacle prevents us from enabling it. Otherwise, we print a warning message and continue running without the sandbox. This is not ideal, but given the non-trivial number of users who might not have seccomp enabled by default, this seems the prudent approach. BUG=26521 Review URL: http://codereview.chromium.org/341092 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30966 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/linux')
-rw-r--r--sandbox/linux/seccomp/sandbox.cc56
-rw-r--r--sandbox/linux/seccomp/sandbox.h1
-rw-r--r--sandbox/linux/seccomp/sandbox_impl.h10
3 files changed, 66 insertions, 1 deletions
diff --git a/sandbox/linux/seccomp/sandbox.cc b/sandbox/linux/seccomp/sandbox.cc
index 1da17d3..9d80f63 100644
--- a/sandbox/linux/seccomp/sandbox.cc
+++ b/sandbox/linux/seccomp/sandbox.cc
@@ -5,13 +5,13 @@
namespace playground {
// Global variables
+enum Sandbox::SandboxStatus Sandbox::status_ = STATUS_UNKNOWN;
int Sandbox::pid_;
int Sandbox::processFdPub_;
int Sandbox::cloneFdPub_;
Sandbox::ProtectedMap Sandbox::protectedMap_;
std::vector<SecureMem::Args*> Sandbox::secureMemPool_;
-
bool Sandbox::sendFd(int transport, int fd0, int fd1, const void* buf,
size_t len) {
int fds[2], count = 0;
@@ -354,7 +354,56 @@ void Sandbox::snapshotMemoryMappings(int processFd) {
}
}
+int Sandbox::supportsSeccompSandbox() {
+ if (status_ != STATUS_UNKNOWN) {
+ return status_ != STATUS_UNSUPPORTED;
+ }
+ int fds[2];
+ SysCalls sys;
+ if (sys.pipe(fds)) {
+ status_ = STATUS_UNSUPPORTED;
+ return 0;
+ }
+ pid_t pid;
+ switch ((pid = sys.fork())) {
+ case -1:
+ status_ = STATUS_UNSUPPORTED;
+ return 0;
+ case 0: {
+ int devnull = sys.open("/dev/null", O_RDWR, 0);
+ if (devnull >= 0) {
+ dup2(devnull, 0);
+ dup2(devnull, 1);
+ dup2(devnull, 2);
+ }
+ startSandbox();
+ write(sys, fds[1], "", 1);
+ _exit(0);
+ sys.exit_group(0);
+ sys._exit(0);
+ }
+ default:
+ NOINTR_SYS(sys.close(fds[1]));
+ char ch;
+ if (read(sys, fds[0], &ch, 1) != 1) {
+ status_ = STATUS_UNSUPPORTED;
+ } else {
+ status_ = STATUS_AVAILABLE;
+ }
+ int rc;
+ NOINTR_SYS(sys.waitpid(pid, &rc, 0));
+ NOINTR_SYS(sys.close(fds[0]));
+ return status_ != STATUS_UNSUPPORTED;
+ }
+}
+
void Sandbox::startSandbox() {
+ if (status_ == STATUS_UNSUPPORTED) {
+ die("The seccomp sandbox is not supported on this computer");
+ } else if (status_ == STATUS_ENABLED) {
+ return;
+ }
+
SysCalls sys;
// The pid is unchanged for the entire program, so we can retrieve it once
@@ -425,6 +474,11 @@ void Sandbox::startSandbox() {
// Creating the trusted thread enables sandboxing
createTrustedThread(processFdPub_, cloneFdPub_, secureMem);
+
+ // We can no longer check for sandboxing support at this point, but we also
+ // know for a fact that it is available (as we just turned it on). So update
+ // the status to reflect this information.
+ status_ = STATUS_ENABLED;
}
} // namespace
diff --git a/sandbox/linux/seccomp/sandbox.h b/sandbox/linux/seccomp/sandbox.h
index 959156b..4c5d10a 100644
--- a/sandbox/linux/seccomp/sandbox.h
+++ b/sandbox/linux/seccomp/sandbox.h
@@ -1,6 +1,7 @@
#ifndef SANDBOX_H__
#define SANDBOX_H__
+extern "C" int SupportsSeccompSandbox();
extern "C" void StartSeccompSandbox();
#endif // SANDBOX_H__
diff --git a/sandbox/linux/seccomp/sandbox_impl.h b/sandbox/linux/seccomp/sandbox_impl.h
index 634f301..d1cc3ef 100644
--- a/sandbox/linux/seccomp/sandbox_impl.h
+++ b/sandbox/linux/seccomp/sandbox_impl.h
@@ -44,6 +44,13 @@ class Sandbox {
public:
enum { kMaxThreads = 100 };
+
+ // There are a lot of reasons why the Seccomp sandbox might not be available.
+ // This could be because the kernel does not support Seccomp mode, or it
+ // could be because we fail to successfully rewrite all system call entry
+ // points.
+ static int supportsSeccompSandbox() asm("SupportsSeccompSandbox");
+
// This is the main public entry point. It finds all system calls that
// need rewriting, sets up the resources needed by the sandbox, and
// enters Seccomp mode.
@@ -602,6 +609,9 @@ class Sandbox {
static void createTrustedThread(int processFdPub, int cloneFdPub,
SecureMem::Args* secureMem);
+ static enum SandboxStatus {
+ STATUS_UNKNOWN, STATUS_UNSUPPORTED, STATUS_AVAILABLE, STATUS_ENABLED
+ } status_;
static int pid_;
static int processFdPub_;
static int cloneFdPub_;