summaryrefslogtreecommitdiffstats
path: root/sandbox/linux/seccomp/securemem.cc
diff options
context:
space:
mode:
authornsylvain@chromium.org <nsylvain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-31 01:16:35 +0000
committernsylvain@chromium.org <nsylvain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-31 01:16:35 +0000
commitfb7b5328a5fd3aecfc27f765dea94b961c657597 (patch)
tree84adc617db0031a881265e95f9c569de66fa733d /sandbox/linux/seccomp/securemem.cc
parent7302ea910ce937d482780649d6a84bbfff4ac521 (diff)
downloadchromium_src-fb7b5328a5fd3aecfc27f765dea94b961c657597.zip
chromium_src-fb7b5328a5fd3aecfc27f765dea94b961c657597.tar.gz
chromium_src-fb7b5328a5fd3aecfc27f765dea94b961c657597.tar.bz2
Revert 57921 - Pull seccomp-sandbox in via DEPS rather than using an in-tree copy
This means changes to the sandbox won't have to be committed twice, to both trees. BUG=none TEST=smoke test of running chromium with --enable-seccomp-sandbox Review URL: http://codereview.chromium.org/3249003 TBR=mseaborn@chromium.org Review URL: http://codereview.chromium.org/3245011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57933 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/linux/seccomp/securemem.cc')
-rw-r--r--sandbox/linux/seccomp/securemem.cc105
1 files changed, 105 insertions, 0 deletions
diff --git a/sandbox/linux/seccomp/securemem.cc b/sandbox/linux/seccomp/securemem.cc
new file mode 100644
index 0000000..5f07bbe
--- /dev/null
+++ b/sandbox/linux/seccomp/securemem.cc
@@ -0,0 +1,105 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "debug.h"
+#include "mutex.h"
+#include "sandbox_impl.h"
+#include "securemem.h"
+
+namespace playground {
+
+void SecureMem::abandonSystemCall(int fd, int err) {
+ void* rc = reinterpret_cast<void *>(err);
+ if (err) {
+ Debug::message("System call failed\n");
+ }
+ Sandbox::SysCalls sys;
+ if (Sandbox::write(sys, fd, &rc, sizeof(rc)) != sizeof(rc)) {
+ Sandbox::die("Failed to send system call");
+ }
+}
+
+void SecureMem::dieIfParentDied(int parentMapsFd) {
+ // The syscall_mutex_ should not be contended. If it is, we are either
+ // experiencing a very unusual load of system calls that the sandbox is not
+ // optimized for; or, more likely, the sandboxed process terminated while the
+ // trusted process was in the middle of waiting for the mutex. We detect
+ // this situation and terminate the trusted process.
+ int alive = !lseek(parentMapsFd, 0, SEEK_SET);
+ if (alive) {
+ char buf;
+ do {
+ alive = read(parentMapsFd, &buf, 1);
+ } while (alive < 0 && errno == EINTR);
+ }
+ if (!alive) {
+ Sandbox::die();
+ }
+}
+
+void SecureMem::lockSystemCall(int parentMapsFd, Args* mem) {
+ while (!Mutex::lockMutex(&Sandbox::syscall_mutex_, 500)) {
+ dieIfParentDied(parentMapsFd);
+ }
+ asm volatile(
+ #if defined(__x86_64__)
+ "lock; incq (%0)\n"
+ #elif defined(__i386__)
+ "lock; incl (%0)\n"
+ #else
+ #error Unsupported target platform
+ #endif
+ :
+ : "q"(&mem->sequence)
+ : "memory");
+}
+
+void SecureMem::sendSystemCallInternal(int fd, bool locked, int parentMapsFd,
+ Args* mem, int syscallNum, void* arg1,
+ void* arg2, void* arg3, void* arg4,
+ void* arg5, void* arg6) {
+ if (!locked) {
+ asm volatile(
+ #if defined(__x86_64__)
+ "lock; incq (%0)\n"
+ #elif defined(__i386__)
+ "lock; incl (%0)\n"
+ #else
+ #error Unsupported target platform
+ #endif
+ :
+ : "q"(&mem->sequence)
+ : "memory");
+ }
+ mem->callType = locked ? -2 : -1;
+ mem->syscallNum = syscallNum;
+ mem->arg1 = arg1;
+ mem->arg2 = arg2;
+ mem->arg3 = arg3;
+ mem->arg4 = arg4;
+ mem->arg5 = arg5;
+ mem->arg6 = arg6;
+ asm volatile(
+ #if defined(__x86_64__)
+ "lock; incq (%0)\n"
+ #elif defined(__i386__)
+ "lock; incl (%0)\n"
+ #else
+ #error Unsupported target platform
+ #endif
+ :
+ : "q"(&mem->sequence)
+ : "memory");
+ Sandbox::SysCalls sys;
+ if (Sandbox::write(sys, fd, &mem->callType, sizeof(int)) != sizeof(int)) {
+ Sandbox::die("Failed to send system call");
+ }
+ if (parentMapsFd >= 0) {
+ while (!Mutex::waitForUnlock(&Sandbox::syscall_mutex_, 500)) {
+ dieIfParentDied(parentMapsFd);
+ }
+ }
+}
+
+} // namespace