| Index: src/trusted/desc/linux/nacl_desc_sysv_shm.c
|
| diff --git a/src/trusted/desc/linux/nacl_desc_sysv_shm.c b/src/trusted/desc/linux/nacl_desc_sysv_shm.c
|
| deleted file mode 100644
|
| index 8e120a9f2bfa00c4771af53a5dbd0f4ab9b67b5e..0000000000000000000000000000000000000000
|
| --- a/src/trusted/desc/linux/nacl_desc_sysv_shm.c
|
| +++ /dev/null
|
| @@ -1,430 +0,0 @@
|
| -/*
|
| - * Copyright (c) 2012 The Native Client Authors. All rights reserved.
|
| - * Use of this source code is governed by a BSD-style license that can be
|
| - * found in the LICENSE file.
|
| - */
|
| -
|
| -/*
|
| - * NaCl Service Runtime. Transferrable shared memory objects.
|
| - */
|
| -
|
| -#include "native_client/src/include/portability.h"
|
| -#include "native_client/src/include/nacl_platform.h"
|
| -
|
| -#include <errno.h>
|
| -#include <stdlib.h>
|
| -#include <string.h>
|
| -#include <sys/types.h>
|
| -#include <sys/shm.h>
|
| -
|
| -#include "native_client/src/trusted/desc/nacl_desc_base.h"
|
| -#include "native_client/src/trusted/desc/nacl_desc_effector.h"
|
| -#include "native_client/src/trusted/desc/linux/nacl_desc_sysv_shm.h"
|
| -
|
| -#include "native_client/src/shared/platform/nacl_find_addrsp.h"
|
| -#include "native_client/src/shared/platform/nacl_log.h"
|
| -#include "native_client/src/shared/platform/nacl_sync_checked.h"
|
| -
|
| -#include "native_client/src/trusted/service_runtime/internal_errno.h"
|
| -#include "native_client/src/trusted/service_runtime/nacl_config.h"
|
| -#include "native_client/src/trusted/service_runtime/include/bits/mman.h"
|
| -#include "native_client/src/trusted/service_runtime/include/sys/errno.h"
|
| -#include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
|
| -#include "native_client/src/trusted/service_runtime/include/sys/stat.h"
|
| -#include "native_client/src/trusted/service_runtime/sel_util.h"
|
| -
|
| -
|
| -#if !defined(SIZE_T_MAX)
|
| -# define SIZE_T_MAX (~((size_t) 0))
|
| -#endif
|
| -
|
| -/*
|
| - * This file contains the implementation of the NaClDescSysvShm
|
| - * subclass of NaClDesc.
|
| - *
|
| - * NaClDescSysvShm is the subclass that wraps SysV shared memory descriptors.
|
| - *
|
| - * Support for SysV shared memory descriptors is much more restricted than
|
| - * for other types of descriptors. In particular:
|
| - * 1) NaCl provides no method for untrusted creation of SysV shared memory.
|
| - * 2) Importing does not confer ownership of the descriptor, and hence
|
| - * we do not do the shmctl(IPC_RMID) to close it. The lifetime of the
|
| - * descriptor is controlled by the X server that created it, and returned
|
| - * it for use by Chrome.
|
| - */
|
| -
|
| -static int NaClDescSysvShmSubclassCtorIntern(struct NaClDescSysvShm *self,
|
| - int id,
|
| - nacl_off64_t size,
|
| - int rmid_in_dtor) {
|
| - struct NaClDesc *basep = (struct NaClDesc *) self;
|
| -
|
| - /*
|
| - * off_t is signed, but size_t is not; historically size_t is for
|
| - * sizeof and similar, and off_t is also used for stat structure
|
| - * st_size member. This runtime test detects large object sizes
|
| - * that are silently converted to negative values. Additionally,
|
| - * the size must be a multiple of 4K.
|
| - */
|
| - basep->base.vtbl = (struct NaClRefCountVtbl const *) NULL;
|
| - if ((size_t) size != NaClRoundPage((size_t) size)
|
| - || size < 0
|
| - || SIZE_T_MAX < (uint64_t) size) {
|
| - return 0;
|
| - }
|
| -
|
| - self->id = id;
|
| - self->size = size;
|
| - self->rmid_in_dtor = rmid_in_dtor;
|
| - basep->base.vtbl = (struct NaClRefCountVtbl const *) &kNaClDescSysvShmVtbl;
|
| - return 1;
|
| -}
|
| -
|
| -static int NaClDescSysvShmCtorIntern(struct NaClDescSysvShm *self,
|
| - int id,
|
| - nacl_off64_t size,
|
| - int rmid_in_dtor) {
|
| - struct NaClDesc *basep = (struct NaClDesc *) self;
|
| - int rv;
|
| -
|
| - NACL_VTBL(NaClRefCount, self) = (struct NaClRefCountVtbl const *) NULL;
|
| -
|
| - if (!NaClDescCtor(basep)) {
|
| - return 0;
|
| - }
|
| - rv = NaClDescSysvShmSubclassCtorIntern(self, id, size, rmid_in_dtor);
|
| - if (!rv) {
|
| - (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self);
|
| - }
|
| - (*NACL_VTBL(NaClDesc, basep)->SetFlags)(basep, NACL_ABI_O_RDWR);
|
| - return rv;
|
| -}
|
| -
|
| -int NaClDescSysvShmImportSubclassCtor(struct NaClDescSysvShm *self,
|
| - int id,
|
| - nacl_off64_t size) {
|
| - return NaClDescSysvShmSubclassCtorIntern(self, id, size, 0);
|
| -}
|
| -
|
| -int NaClDescSysvShmImportCtor(struct NaClDescSysvShm *self,
|
| - int id,
|
| - nacl_off64_t size) {
|
| - return NaClDescSysvShmCtorIntern(self, id, size, 0);
|
| -}
|
| -
|
| -/*
|
| - * Creates a NaClDesc containing a new shared memory region.
|
| - */
|
| -int NaClDescSysvShmCtor(struct NaClDescSysvShm *self,
|
| - nacl_off64_t size) {
|
| - int id;
|
| - int retval;
|
| -
|
| - if (size < 0 || SIZE_T_MAX < (uint64_t) size) {
|
| - return 0;
|
| - }
|
| - /* Create the region. */
|
| - id = shmget(IPC_PRIVATE,
|
| - (int) size,
|
| - IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
|
| - if (-1 == id) {
|
| - return 0;
|
| - }
|
| - /* Construct the descriptor. */
|
| - retval = NaClDescSysvShmCtorIntern(self, id, size, 1);
|
| - /* If the constructor failed, mark the region for freeing. */
|
| - if (0 == retval) {
|
| - (void) shmctl(id, IPC_RMID, NULL);
|
| - return 0;
|
| - }
|
| - /* Return success. */
|
| - return 1;
|
| -}
|
| -
|
| -static void NaClDescSysvShmDtor(struct NaClRefCount *vself) {
|
| - struct NaClDescSysvShm *self = (struct NaClDescSysvShm *) vself;
|
| -
|
| - /*
|
| - * Importing does NOT confer ownership of the id. Hence the Dtor does not
|
| - * do the shmctl(IPC_RMID).
|
| - */
|
| - if (self->rmid_in_dtor) {
|
| - (void) shmctl(self->id, IPC_RMID, NULL);
|
| - }
|
| - /* NACL_INVALID_HANDLE is also an invalid id for shmat. */
|
| - self->id = NACL_INVALID_HANDLE;
|
| - vself->vtbl = (struct NaClRefCountVtbl const *) &kNaClDescVtbl;
|
| - (*vself->vtbl->Dtor)(vself);
|
| -}
|
| -
|
| -/*
|
| - * For now, we just use shmat. This means that the NaCl module's mmap
|
| - * syscall must ask for the entire size, with a zero offset. In the
|
| - * future, we may choose to shmat to elsewhere in the trusted address
|
| - * space, and then mremap from there into the untrusted address space,
|
| - * using MREMAP_FIXED to ask for the new location. This approach has
|
| - * its own hazards, however since on x86-32 we are short on address
|
| - * space already, and requiring shmat, mremap, munmap means that we
|
| - * have to have enough trusted address space free to temporarily hold
|
| - * the maximum sized sysv shm object.
|
| - */
|
| -static uintptr_t NaClDescSysvShmMap(struct NaClDesc *vself,
|
| - struct NaClDescEffector *effp,
|
| - void *start_addr,
|
| - size_t len,
|
| - int prot,
|
| - int flags,
|
| - nacl_off64_t offset) {
|
| - struct NaClDescSysvShm *self = (struct NaClDescSysvShm *) vself;
|
| -
|
| - int host_flags;
|
| - void *result;
|
| -
|
| - UNREFERENCED_PARAMETER(effp);
|
| -
|
| - NaClLog(4,
|
| - "NaClDescSysVShmMmap(,,0x%08"NACL_PRIxPTR",0x%"NACL_PRIxS","
|
| - "0x%x,0x%x,0x%08"NACL_PRIxNACL_OFF64")\n",
|
| - (uintptr_t) start_addr, len, prot, flags, offset);
|
| - /*
|
| - * shm must have NACL_ABI_MAP_SHARED in flags. we check, and may
|
| - * relax this in the future.
|
| - */
|
| - if ((NACL_ABI_MAP_SHARED) !=
|
| - (flags & (NACL_ABI_MAP_SHARING_MASK))) {
|
| - NaClLog(LOG_INFO,
|
| - ("NaClDescSysvShmMap: Mapping not"
|
| - " NACL_ABI_MAP_SHARED\n"));
|
| - return -NACL_ABI_EINVAL;
|
| - }
|
| -
|
| - if (0 != (NACL_ABI_MAP_FIXED & flags) && NULL == start_addr) {
|
| - NaClLog(LOG_INFO,
|
| - ("NaClDescSysvShmMap: Mapping NACL_ABI_MAP_FIXED"
|
| - " but start_addr is NULL\n"));
|
| - return -NACL_ABI_EINVAL;
|
| - }
|
| - /* post-condition: if NULL == start_addr, then NACL_ABI_MAP_FIXED not set */
|
| -
|
| - if (NULL == start_addr) {
|
| - uintptr_t addr;
|
| -
|
| - if (!NaClFindAddressSpace(&addr, len)) {
|
| - NaClLog(1, "NaClDescSysvShmMap: could not find address space\n");
|
| - return -NACL_ABI_ENOMEM;
|
| - }
|
| - if (-1 == munmap((void *) addr, len)) {
|
| - NaClLog(LOG_FATAL,
|
| - "Could not unmap found space at 0x%"NACL_PRIxPTR"\n",
|
| - addr);
|
| - }
|
| - start_addr = (void *) addr;
|
| - }
|
| -
|
| - /*
|
| - * shmat can only map the shared memory region starting at its beginning
|
| - * and continuing for its entire size.
|
| - */
|
| - if (0 != offset || self->size > len) {
|
| - NaClLog(LOG_INFO,
|
| - "NaClDescSysvShmMap: Mapping at non-zero offset or length"
|
| - " mismatch\n");
|
| - return -NACL_ABI_EINVAL;
|
| - }
|
| - /*
|
| - * prot must be not be PROT_NONE nor contain other than PROT_{READ|WRITE}
|
| - */
|
| - if (NACL_ABI_PROT_NONE == prot) {
|
| - NaClLog(LOG_INFO, "NaClDescSysvShmMap: PROT_NONE not supported\n");
|
| - return -NACL_ABI_EINVAL;
|
| - }
|
| - if (0 == (NACL_ABI_PROT_READ & prot)) {
|
| - NaClLog(LOG_INFO, "NaClDescSysvShmMap: PROT_READ not set\n");
|
| - return -NACL_ABI_EINVAL;
|
| - }
|
| - if (0 != (~(NACL_ABI_PROT_READ | NACL_ABI_PROT_WRITE) & prot)) {
|
| - NaClLog(LOG_INFO,
|
| - "NaClDescSysvShmMap: prot has other bits than PROT_{READ|WRITE}\n");
|
| - return -NACL_ABI_EINVAL;
|
| - }
|
| - /*
|
| - * Map from NACL_ABI_ prot and flags bits to shmat flags.
|
| - */
|
| - host_flags = SHM_REMAP;
|
| - if (NACL_ABI_PROT_READ == prot) {
|
| - host_flags |= SHM_RDONLY;
|
| - }
|
| -
|
| - /*
|
| - * TODO(bsy): !NACL_ABI_MAP_FIXED, start_addr == NULL, find address
|
| - * space (assuming no race), and set start_addr appropriately.
|
| - *
|
| - * If SHM_REMAP is defined, use it. Else munmap and then shmat,
|
| - * leaving a timing hole for multithreaded race. Fail if we lose
|
| - * the race and let the user code retry.
|
| - */
|
| - /*
|
| - * Attach (map) the shared memory region.
|
| - */
|
| - result = shmat(self->id, (void *) start_addr, host_flags);
|
| - if (NACL_MAP_FAILED == result) {
|
| - NaClLog(LOG_FATAL, "NaClDescSysvMap: shmat failed %d\n", errno);
|
| - }
|
| - if (result != start_addr) {
|
| - NaClLog(LOG_FATAL,
|
| - ("NaClDescSysvShmMap: NACL_MAP_FIXED but"
|
| - " got 0x%08"NACL_PRIxPTR" instead of 0x%08"NACL_PRIxPTR"\n"),
|
| - (uintptr_t) result, (uintptr_t) start_addr);
|
| - }
|
| -
|
| - return (uintptr_t) start_addr;
|
| -}
|
| -
|
| -static int NaClDescSysvShmFstat(struct NaClDesc *vself,
|
| - struct nacl_abi_stat *stbp) {
|
| - struct NaClDescSysvShm *self = (struct NaClDescSysvShm *) vself;
|
| -
|
| - if (self->size > INT32_MAX) {
|
| - return -NACL_ABI_EOVERFLOW;
|
| - }
|
| -
|
| - stbp->nacl_abi_st_dev = 0;
|
| - stbp->nacl_abi_st_ino = 0x6c43614e;
|
| - stbp->nacl_abi_st_mode = (NACL_ABI_S_IFSHM_SYSV |
|
| - NACL_ABI_S_IRUSR |
|
| - NACL_ABI_S_IWUSR);
|
| - stbp->nacl_abi_st_nlink = 1;
|
| - stbp->nacl_abi_st_uid = -1;
|
| - stbp->nacl_abi_st_gid = -1;
|
| - stbp->nacl_abi_st_rdev = 0;
|
| - /* TODO(sehr): this should really use shmctl instead. */
|
| - stbp->nacl_abi_st_size = (nacl_abi_off_t) self->size;
|
| - stbp->nacl_abi_st_blksize = 0;
|
| - stbp->nacl_abi_st_blocks = 0;
|
| - stbp->nacl_abi_st_atime = 0;
|
| - stbp->nacl_abi_st_mtime = 0;
|
| - stbp->nacl_abi_st_ctime = 0;
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -static int NaClDescSysvShmExternalizeSize(struct NaClDesc *vself,
|
| - size_t *nbytes,
|
| - size_t *nhandles) {
|
| - struct NaClDescSysvShm *self = (struct NaClDescSysvShm *) vself;
|
| - int rv;
|
| -
|
| - rv = NaClDescExternalizeSize(vself, nbytes, nhandles);
|
| - if (0 != rv) {
|
| - return rv;
|
| - }
|
| - *nbytes += sizeof self->id + sizeof(nacl_off64_t);
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -static int NaClDescSysvShmExternalize(struct NaClDesc *vself,
|
| - struct NaClDescXferState *xfer) {
|
| - struct NaClDescSysvShm *self = (struct NaClDescSysvShm *) vself;
|
| - nacl_off64_t size64 = self->size;
|
| - int rv;
|
| -
|
| - rv = NaClDescExternalize(vself, xfer);
|
| - if (0 != rv) {
|
| - return rv;
|
| - }
|
| - memcpy(xfer->next_byte, &self->id, sizeof self->id);
|
| - xfer->next_byte += sizeof self->id;
|
| - memcpy(xfer->next_byte, &size64, sizeof size64);
|
| - xfer->next_byte += sizeof size64;
|
| - return 0;
|
| -}
|
| -
|
| -struct NaClDescVtbl const kNaClDescSysvShmVtbl = {
|
| - {
|
| - NaClDescSysvShmDtor,
|
| - },
|
| - NaClDescSysvShmMap,
|
| - NACL_DESC_UNMAP_NOT_IMPLEMENTED
|
| - NaClDescReadNotImplemented,
|
| - NaClDescWriteNotImplemented,
|
| - NaClDescSeekNotImplemented,
|
| - NaClDescPReadNotImplemented,
|
| - NaClDescPWriteNotImplemented,
|
| - NaClDescSysvShmFstat,
|
| - NaClDescGetdentsNotImplemented,
|
| - NaClDescSysvShmExternalizeSize,
|
| - NaClDescSysvShmExternalize,
|
| - NaClDescLockNotImplemented,
|
| - NaClDescTryLockNotImplemented,
|
| - NaClDescUnlockNotImplemented,
|
| - NaClDescWaitNotImplemented,
|
| - NaClDescTimedWaitAbsNotImplemented,
|
| - NaClDescSignalNotImplemented,
|
| - NaClDescBroadcastNotImplemented,
|
| - NaClDescSendMsgNotImplemented,
|
| - NaClDescRecvMsgNotImplemented,
|
| - NaClDescLowLevelSendMsgNotImplemented,
|
| - NaClDescLowLevelRecvMsgNotImplemented,
|
| - NaClDescConnectAddrNotImplemented,
|
| - NaClDescAcceptConnNotImplemented,
|
| - NaClDescPostNotImplemented,
|
| - NaClDescSemWaitNotImplemented,
|
| - NaClDescGetValueNotImplemented,
|
| - NaClDescSetMetadata,
|
| - NaClDescGetMetadata,
|
| - NaClDescSetFlags,
|
| - NaClDescGetFlags,
|
| - NaClDescIsattyNotImplemented,
|
| - NACL_DESC_SYSV_SHM,
|
| -};
|
| -
|
| -int NaClDescSysvShmInternalize(struct NaClDesc **out_desc,
|
| - struct NaClDescXferState *xfer,
|
| - struct NaClDescQuotaInterface *quota_interface) {
|
| - int rv;
|
| - struct NaClDescSysvShm *ndisp;
|
| - int id;
|
| - nacl_off64_t size;
|
| -
|
| - UNREFERENCED_PARAMETER(quota_interface);
|
| - rv = -NACL_ABI_EIO;
|
| -
|
| - ndisp = malloc(sizeof *ndisp);
|
| - if (NULL == ndisp) {
|
| - rv = -NACL_ABI_ENOMEM;
|
| - goto cleanup;
|
| - }
|
| -
|
| - if (!NaClDescInternalizeCtor((struct NaClDesc *) ndisp, xfer)) {
|
| - free(ndisp);
|
| - ndisp = NULL;
|
| - rv = -NACL_ABI_ENOMEM;
|
| - goto cleanup;
|
| - }
|
| -
|
| - if (xfer->next_byte + sizeof ndisp->id + sizeof ndisp->size >
|
| - xfer->byte_buffer_end) {
|
| - rv = -NACL_ABI_EIO;
|
| - goto cleanup;
|
| - }
|
| -
|
| - memcpy(&id, xfer->next_byte, sizeof id);
|
| - xfer->next_byte += sizeof id;
|
| - memcpy(&size, xfer->next_byte, sizeof size);
|
| - xfer->next_byte += sizeof size;
|
| -
|
| - if (!NaClDescSysvShmImportSubclassCtor(ndisp, id, size)) {
|
| - rv = -NACL_ABI_EIO;
|
| - goto cleanup;
|
| - }
|
| -
|
| - *out_desc = (struct NaClDesc *) ndisp;
|
| - rv = 0;
|
| -
|
| -cleanup:
|
| - if (rv < 0) {
|
| - NaClDescSafeUnref((struct NaClDesc *) ndisp);
|
| - }
|
| - return rv;
|
| -}
|
|
|