static int NaClDescImcShmUnmapUnsafe(struct NaClDesc *vself, void *start_addr, size_t len) { int retval; uintptr_t addr; uintptr_t end_addr; UNREFERENCED_PARAMETER(vself); retval = -NACL_ABI_EINVAL; for (addr = (uintptr_t) start_addr, end_addr = addr + len; addr < end_addr; addr += NACL_MAP_PAGESIZE) { int status; /* * On windows, we must unmap "properly", since overmapping will * not tear down existing page mappings. */ status = NaClUnmap((void *) addr, NACL_MAP_PAGESIZE); if (0 != status) { NaClLog(LOG_FATAL, "NaClDescImcShmUnmapCommon: NaClUnmap failed\n"); goto done; } } retval = 0; done: return retval; }
static int NaClDescImcShmUnmapCommon(struct NaClDesc *vself, struct NaClDescEffector *effp, void *start_addr, size_t len, int safe_mode) { int retval; uintptr_t addr; uintptr_t end_addr; UNREFERENCED_PARAMETER(vself); retval = -NACL_ABI_EINVAL; for (addr = (uintptr_t) start_addr, end_addr = addr + len; addr < end_addr; addr += NACL_MAP_PAGESIZE) { int status; if (!safe_mode) { /* * unsafe unmap always unmaps, w/o overmapping with anonymous * memory. this is not necessary (nor desired) in safe_mode, * since overmapping with anonymous memory will atomically tear * down the mappings for these pages without leaving a timing * window open where the untrusted address space has unoccupied * page table entries. */ /* * Do the unmap "properly" through NaClUnmap. */ status = NaClUnmap((void *) addr, NACL_MAP_PAGESIZE); if (0 != status) { NaClLog(LOG_FATAL, "NaClDescImcShmUnmapCommon: NaClUnmap failed\n"); goto done; } } /* there's still a race condition */ if (safe_mode) { uintptr_t result = (*effp->vtbl->MapAnonymousMemory)(effp, addr, NACL_MAP_PAGESIZE, PROT_NONE); if (NaClPtrIsNegErrno(&result)) { NaClLog(LOG_ERROR, "NaClDescImcShmUnmapCommon: could not fill hole\n"); retval = -NACL_ABI_E_MOVE_ADDRESS_SPACE; goto done; } } } retval = 0; done: return retval; }