| 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
|
|
|