Index: sandbox/linux/seccomp/ipc.cc |
=================================================================== |
--- sandbox/linux/seccomp/ipc.cc (revision 57969) |
+++ sandbox/linux/seccomp/ipc.cc (working copy) |
@@ -1,351 +0,0 @@ |
-// 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 "sandbox_impl.h" |
- |
-namespace playground { |
- |
-#ifndef IPC_PRIVATE |
-#define IPC_PRIVATE 0 |
-#endif |
-#ifndef IPC_RMID |
-#define IPC_RMID 0 |
-#endif |
-#ifndef IPC_64 |
-#define IPC_64 256 |
-#endif |
- |
-#if defined(__NR_shmget) |
-void* Sandbox::sandbox_shmat(int shmid, const void* shmaddr, int shmflg) { |
- long long tm; |
- Debug::syscall(&tm, __NR_shmat, "Executing handler"); |
- |
- struct { |
- int sysnum; |
- long long cookie; |
- ShmAt shmat_req; |
- } __attribute__((packed)) request; |
- request.sysnum = __NR_shmat; |
- request.cookie = cookie(); |
- request.shmat_req.shmid = shmid; |
- request.shmat_req.shmaddr = shmaddr; |
- request.shmat_req.shmflg = shmflg; |
- |
- 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 shmat() request [sandbox]"); |
- } |
- Debug::elapsed(tm, __NR_shmat); |
- return reinterpret_cast<void *>(rc); |
-} |
- |
-long Sandbox::sandbox_shmctl(int shmid, int cmd, void* buf) { |
- long long tm; |
- Debug::syscall(&tm, __NR_shmctl, "Executing handler"); |
- |
- struct { |
- int sysnum; |
- long long cookie; |
- ShmCtl shmctl_req; |
- } __attribute__((packed)) request; |
- request.sysnum = __NR_shmctl; |
- request.cookie = cookie(); |
- request.shmctl_req.shmid = shmid; |
- request.shmctl_req.cmd = cmd; |
- request.shmctl_req.buf = buf; |
- |
- 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 shmctl() request [sandbox]"); |
- } |
- Debug::elapsed(tm, __NR_shmctl); |
- return rc; |
-} |
- |
-long Sandbox::sandbox_shmdt(const void* shmaddr) { |
- long long tm; |
- Debug::syscall(&tm, __NR_shmdt, "Executing handler"); |
- |
- struct { |
- int sysnum; |
- long long cookie; |
- ShmDt shmdt_req; |
- } __attribute__((packed)) request; |
- request.sysnum = __NR_shmdt; |
- request.cookie = cookie(); |
- request.shmdt_req.shmaddr = shmaddr; |
- |
- 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 shmdt() request [sandbox]"); |
- } |
- Debug::elapsed(tm, __NR_shmdt); |
- return rc; |
-} |
- |
-long Sandbox::sandbox_shmget(int key, size_t size, int shmflg) { |
- long long tm; |
- Debug::syscall(&tm, __NR_shmget, "Executing handler"); |
- |
- struct { |
- int sysnum; |
- long long cookie; |
- ShmGet shmget_req; |
- } __attribute__((packed)) request; |
- request.sysnum = __NR_shmget; |
- request.cookie = cookie(); |
- request.shmget_req.key = key; |
- request.shmget_req.size = size; |
- request.shmget_req.shmflg = shmflg; |
- |
- 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 shmget() request [sandbox]"); |
- } |
- Debug::elapsed(tm, __NR_shmget); |
- return rc; |
-} |
- |
-bool Sandbox::process_shmat(int parentMapsFd, int sandboxFd, int threadFdPub, |
- int threadFd, SecureMem::Args* mem) { |
- // Read request |
- ShmAt shmat_req; |
- SysCalls sys; |
- if (read(sys, sandboxFd, &shmat_req, sizeof(shmat_req)) != |
- sizeof(shmat_req)) { |
- die("Failed to read parameters for shmat() [process]"); |
- } |
- |
- // We only allow attaching to the shm identifier that was returned by |
- // the most recent call to shmget(IPC_PRIVATE) |
- if (shmat_req.shmaddr || shmat_req.shmflg || shmat_req.shmid != mem->shmId) { |
- mem->shmId = -1; |
- SecureMem::abandonSystemCall(threadFd, -EINVAL); |
- return false; |
- } |
- |
- mem->shmId = -1; |
- SecureMem::sendSystemCall(threadFdPub, false, -1, mem, |
- __NR_shmat, shmat_req.shmid, shmat_req.shmaddr, |
- shmat_req.shmflg); |
- return true; |
-} |
- |
-bool Sandbox::process_shmctl(int parentMapsFd, int sandboxFd, int threadFdPub, |
- int threadFd, SecureMem::Args* mem) { |
- // Read request |
- ShmCtl shmctl_req; |
- SysCalls sys; |
- if (read(sys, sandboxFd, &shmctl_req, sizeof(shmctl_req)) != |
- sizeof(shmctl_req)) { |
- die("Failed to read parameters for shmctl() [process]"); |
- } |
- |
- // The only shmctl() operation that we need to support is removal. This |
- // operation is generally safe. |
- if ((shmctl_req.cmd & ~(IPC_64 | IPC_RMID)) || shmctl_req.buf) { |
- mem->shmId = -1; |
- SecureMem::abandonSystemCall(threadFd, -EINVAL); |
- return false; |
- } |
- |
- mem->shmId = -1; |
- SecureMem::sendSystemCall(threadFdPub, false, -1, mem, |
- __NR_shmctl, shmctl_req.shmid, shmctl_req.cmd, |
- shmctl_req.buf); |
- return true; |
-} |
- |
-bool Sandbox::process_shmdt(int parentMapsFd, int sandboxFd, int threadFdPub, |
- int threadFd, SecureMem::Args* mem) { |
- // Read request |
- ShmDt shmdt_req; |
- SysCalls sys; |
- if (read(sys, sandboxFd, &shmdt_req, sizeof(shmdt_req)) != |
- sizeof(shmdt_req)) { |
- die("Failed to read parameters for shmdt() [process]"); |
- } |
- |
- // Detaching shared memory segments it generally safe, but just in case |
- // of a kernel bug, we make sure that the address does not fall into any |
- // of the reserved memory regions. |
- ProtectedMap::const_iterator iter = protectedMap_.lower_bound( |
- (void *)shmdt_req.shmaddr); |
- if (iter != protectedMap_.begin()) { |
- --iter; |
- } |
- for (; iter != protectedMap_.end() && iter->first <= shmdt_req.shmaddr; |
- ++iter){ |
- if (shmdt_req.shmaddr < reinterpret_cast<void *>( |
- reinterpret_cast<char *>(iter->first) + iter->second) && |
- shmdt_req.shmaddr >= iter->first) { |
- mem->shmId = -1; |
- SecureMem::abandonSystemCall(threadFd, -EINVAL); |
- return false; |
- } |
- } |
- |
- mem->shmId = -1; |
- SecureMem::sendSystemCall(threadFdPub, false, -1, mem, |
- __NR_shmdt, shmdt_req.shmaddr); |
- return true; |
-} |
- |
-bool Sandbox::process_shmget(int parentMapsFd, int sandboxFd, int threadFdPub, |
- int threadFd, SecureMem::Args* mem) { |
- // Read request |
- ShmGet shmget_req; |
- SysCalls sys; |
- if (read(sys, sandboxFd, &shmget_req, sizeof(shmget_req)) != |
- sizeof(shmget_req)) { |
- die("Failed to read parameters for shmget() [process]"); |
- } |
- |
- // We do not want to allow the sandboxed application to access arbitrary |
- // shared memory regions. We only allow it to access regions that it |
- // created itself. |
- if (shmget_req.key != IPC_PRIVATE || shmget_req.shmflg & ~0777) { |
- mem->shmId = -1; |
- SecureMem::abandonSystemCall(threadFd, -EINVAL); |
- return false; |
- } |
- |
- mem->shmId = -1; |
- SecureMem::sendSystemCall(threadFdPub, false, -1, mem, |
- __NR_shmget, shmget_req.key, shmget_req.size, |
- shmget_req.shmflg); |
- return true; |
-} |
-#endif |
- |
-#if defined(__NR_ipc) |
-#ifndef SHMAT |
-#define SHMAT 21 |
-#endif |
-#ifndef SHMDT |
-#define SHMDT 22 |
-#endif |
-#ifndef SHMGET |
-#define SHMGET 23 |
-#endif |
-#ifndef SHMCTL |
-#define SHMCTL 24 |
-#endif |
- |
-long Sandbox::sandbox_ipc(unsigned call, int first, int second, int third, |
- void* ptr, long fifth) { |
- long long tm; |
- Debug::syscall(&tm, __NR_ipc, "Executing handler", call); |
- struct { |
- int sysnum; |
- long long cookie; |
- IPC ipc_req; |
- } __attribute__((packed)) request; |
- request.sysnum = __NR_ipc; |
- request.cookie = cookie(); |
- request.ipc_req.call = call; |
- request.ipc_req.first = first; |
- request.ipc_req.second = second; |
- request.ipc_req.third = third; |
- request.ipc_req.ptr = ptr; |
- request.ipc_req.fifth = fifth; |
- |
- 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 ipc() request [sandbox]"); |
- } |
- Debug::elapsed(tm, __NR_ipc, call); |
- return rc; |
-} |
- |
-bool Sandbox::process_ipc(int parentMapsFd, int sandboxFd, int threadFdPub, |
- int threadFd, SecureMem::Args* mem) { |
- // Read request |
- IPC ipc_req; |
- SysCalls sys; |
- if (read(sys, sandboxFd, &ipc_req, sizeof(ipc_req)) != sizeof(ipc_req)) { |
- die("Failed to read parameters for ipc() [process]"); |
- } |
- |
- // We do not support all of the SysV IPC calls. In fact, we only support |
- // the minimum feature set necessary for Chrome's renderers to share memory |
- // with the X server. |
- switch (ipc_req.call) { |
- case SHMAT: { |
- // We only allow attaching to the shm identifier that was returned by |
- // the most recent call to shmget(IPC_PRIVATE) |
- if (ipc_req.ptr || ipc_req.second || ipc_req.first != mem->shmId) { |
- goto deny; |
- } |
- accept: |
- mem->shmId = -1; |
- SecureMem::sendSystemCall(threadFdPub, false, -1, mem, |
- __NR_ipc, ipc_req.call, ipc_req.first, |
- ipc_req.second, ipc_req.third, ipc_req.ptr, |
- ipc_req.fifth); |
- return true; |
- } |
- case SHMCTL: |
- // The only shmctl() operation that we need to support is removal. This |
- // operation is generally safe. |
- if ((ipc_req.second & ~(IPC_64 | IPC_RMID)) || ipc_req.ptr) { |
- goto deny; |
- } else { |
- goto accept; |
- } |
- case SHMDT: { |
- // Detaching shared memory segments it generally safe, but just in case |
- // of a kernel bug, we make sure that the address does not fall into any |
- // of the reserved memory regions. |
- ProtectedMap::const_iterator iter = protectedMap_.lower_bound( |
- (void *)ipc_req.ptr); |
- if (iter != protectedMap_.begin()) { |
- --iter; |
- } |
- for (; iter != protectedMap_.end() && iter->first <=ipc_req.ptr; ++iter){ |
- if (ipc_req.ptr < reinterpret_cast<void *>( |
- reinterpret_cast<char *>(iter->first) + iter->second) && |
- ipc_req.ptr >= iter->first) { |
- goto deny; |
- } |
- } |
- goto accept; |
- } |
- case SHMGET: |
- // We do not want to allow the sandboxed application to access arbitrary |
- // shared memory regions. We only allow it to access regions that it |
- // created itself. |
- if (ipc_req.first != IPC_PRIVATE || ipc_req.third & ~0777) { |
- goto deny; |
- } else { |
- goto accept; |
- } |
- default: |
- // Other than SysV shared memory, we do not actually need to support any |
- // other SysV IPC calls. |
- deny: |
- mem->shmId = -1; |
- SecureMem::abandonSystemCall(threadFd, -EINVAL); |
- return false; |
- } |
-} |
-#endif |
- |
-} // namespace |