summaryrefslogtreecommitdiffstats
path: root/sandbox/linux/seccomp/clone.cc
diff options
context:
space:
mode:
authormarkus@chromium.org <markus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-11 21:46:07 +0000
committermarkus@chromium.org <markus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-11 21:46:07 +0000
commit0fb2bd939380e4d46bad10eb597bff4980ca7db2 (patch)
tree79d017b24dfb4d91059b856da7b8ad43764d76e6 /sandbox/linux/seccomp/clone.cc
parent135b165d2bca7a9a7302eb4f771dc713c8100edb (diff)
downloadchromium_src-0fb2bd939380e4d46bad10eb597bff4980ca7db2.zip
chromium_src-0fb2bd939380e4d46bad10eb597bff4980ca7db2.tar.gz
chromium_src-0fb2bd939380e4d46bad10eb597bff4980ca7db2.tar.bz2
Initial version of the Seccomp sandbox. Imported from http://code.google.com/p/seccompsandbox/
Make the seccomp sandbox dependant on the --enable-seccomp-sandbox flag Review URL: http://codereview.chromium.org/165310 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23087 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/linux/seccomp/clone.cc')
-rw-r--r--sandbox/linux/seccomp/clone.cc111
1 files changed, 111 insertions, 0 deletions
diff --git a/sandbox/linux/seccomp/clone.cc b/sandbox/linux/seccomp/clone.cc
new file mode 100644
index 0000000..109e5c6
--- /dev/null
+++ b/sandbox/linux/seccomp/clone.cc
@@ -0,0 +1,111 @@
+#include "debug.h"
+#include "sandbox_impl.h"
+
+namespace playground {
+
+int Sandbox::sandbox_clone(int flags, void* stack, int* pid, int* ctid,
+ void* tls, void *wrapper_sp) {
+ Debug::syscall(__NR_clone, "Executing handler");
+ struct {
+ int sysnum;
+ long long cookie;
+ Clone clone_req;
+ } __attribute__((packed)) request;
+ request.sysnum = __NR_clone;
+ request.cookie = cookie();
+ request.clone_req.flags = flags;
+ request.clone_req.stack = stack;
+ request.clone_req.pid = pid;
+ request.clone_req.ctid = ctid;
+ request.clone_req.tls = tls;
+
+ // Pass along the address on the stack where syscallWrapper() stored the
+ // original CPU registers. These registers will be restored in the newly
+ // created thread prior to returning from the wrapped system call.
+ #if defined(__x86_64__)
+ memcpy(&request.clone_req.regs64, wrapper_sp,
+ sizeof(request.clone_req.regs64) + sizeof(void *));
+ #elif defined(__i386__)
+ memcpy(&request.clone_req.regs32, wrapper_sp,
+ sizeof(request.clone_req.regs32) + sizeof(void *));
+ #else
+ #error Unsupported target platform
+ #endif
+
+ long rc;
+ SysCalls sys;
+ if (write(sys, processFdPub(), &request, sizeof(request)) !=
+ sizeof(request) ||
+ read(sys, threadFdPub(), &rc, sizeof(rc)) != sizeof(rc)) {
+ die("Failed to forward clone() request [sandbox]");
+ }
+ return static_cast<int>(rc);
+}
+
+bool Sandbox::process_clone(int parentProc, int sandboxFd, int threadFdPub,
+ int threadFd, SecureMem::Args* mem) {
+ // Read request
+ Clone clone_req;
+ SysCalls sys;
+ if (read(sys, sandboxFd, &clone_req, sizeof(clone_req)) !=sizeof(clone_req)){
+ die("Failed to read parameters for clone() [process]");
+ }
+
+ // TODO(markus): add policy restricting parameters for clone
+ if ((clone_req.flags & ~CLONE_DETACHED) != (CLONE_VM|CLONE_FS|CLONE_FILES|
+ CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|
+ CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID)) {
+ SecureMem::abandonSystemCall(threadFd, -EPERM);
+ return false;
+ } else {
+ SecureMem::Args* newMem = getSecureMem();
+ if (!newMem) {
+ SecureMem::abandonSystemCall(threadFd, -ENOMEM);
+ return false;
+ } else {
+ // clone() has unusual semantics. We don't want to return back into the
+ // trusted thread, but instead we need to continue execution at the IP
+ // where we got called initially.
+ SecureMem::lockSystemCall(parentProc, mem);
+ mem->ret = clone_req.ret;
+ #if defined(__x86_64__)
+ mem->rbp = clone_req.regs64.rbp;
+ mem->rbx = clone_req.regs64.rbx;
+ mem->rcx = clone_req.regs64.rcx;
+ mem->rdx = clone_req.regs64.rdx;
+ mem->rsi = clone_req.regs64.rsi;
+ mem->rdi = clone_req.regs64.rdi;
+ mem->r8 = clone_req.regs64.r8;
+ mem->r9 = clone_req.regs64.r9;
+ mem->r10 = clone_req.regs64.r10;
+ mem->r11 = clone_req.regs64.r11;
+ mem->r12 = clone_req.regs64.r12;
+ mem->r13 = clone_req.regs64.r13;
+ mem->r14 = clone_req.regs64.r14;
+ mem->r15 = clone_req.regs64.r15;
+ #elif defined(__i386__)
+ mem->ret2 = clone_req.regs32.ret2;
+ mem->ebp = clone_req.regs32.ebp;
+ mem->edi = clone_req.regs32.edi;
+ mem->esi = clone_req.regs32.esi;
+ mem->edx = clone_req.regs32.edx;
+ mem->ecx = clone_req.regs32.ecx;
+ mem->ebx = clone_req.regs32.ebx;
+ #else
+ #error Unsupported target platform
+ #endif
+ newMem->sequence = 0;
+ newMem->shmId = -1;
+ mem->newSecureMem = newMem;
+ mem->processFdPub = processFdPub_;
+ mem->cloneFdPub = cloneFdPub_;
+
+ SecureMem::sendSystemCall(threadFdPub, true, parentProc, mem, __NR_clone,
+ clone_req.flags, clone_req.stack,
+ clone_req.pid, clone_req.ctid, clone_req.tls);
+ return true;
+ }
+ }
+}
+
+} // namespace