Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2012 The Native Client Authors. All rights reserved. | |
| 3 * Use of this source code is governed by a BSD-style license that can | |
| 4 * be found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 #include "native_client/src/include/nacl_platform.h" | |
| 8 #include "native_client/src/shared/platform/nacl_check.h" | |
| 9 #include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h" | |
| 10 #include "native_client/src/trusted/service_runtime/nacl_error_code.h" | |
| 11 #include "native_client/src/trusted/service_runtime/sel_addrspace.h" | |
| 12 #include "native_client/src/trusted/service_runtime/sel_ldr.h" | |
| 13 #include "native_client/src/trusted/service_runtime/sel_memory.h" | |
| 14 | |
| 15 | |
| 16 /* NOTE: This routine is almost identical to the x86_32 version. | |
| 17 */ | |
| 18 NaClErrorCode NaClAllocateSpace(void **mem, size_t addrsp_size) { | |
| 19 int result; | |
| 20 void *tmp_mem = (void *) NACL_TRAMPOLINE_START; | |
| 21 | |
| 22 CHECK(NULL != mem); | |
| 23 | |
| 24 /* | |
| 25 * On Mips, we also cheat slightly: we add two pages to the requested | |
| 26 * allocation! This accomodates the guard region we require at the | |
| 27 * top end of untrusted memory. | |
| 28 */ | |
| 29 addrsp_size += NACL_ADDRSPACE_UPPER_GUARD_SIZE; | |
| 30 | |
| 31 NaClAddrSpaceBeforeAlloc(addrsp_size); | |
| 32 | |
| 33 /* | |
| 34 * On 32 bit Linux, a 1 gigabyte block of address space may be reserved at | |
| 35 * the zero-end of the address space during process creation, to address | |
| 36 * sandbox layout requirements on Mips and performance issues on Intel ATOM. | |
| 37 * Look for this pre-reserved block and if found, pass its address to the | |
| 38 * page allocation function. | |
| 39 */ | |
| 40 if (!NaClFindPrereservedSandboxMemory(mem, addrsp_size)) { | |
| 41 /* On Mips, we should always have prereserved sandbox memory. */ | |
| 42 NaClLog(LOG_ERROR, "NaClAllocateSpace:" | |
| 43 " Could not find correct amount of prereserved memory" | |
| 44 " (looked for 0x%016"NACL_PRIxS" bytes).\n", | |
| 45 addrsp_size); | |
| 46 return LOAD_NO_MEMORY; | |
| 47 } | |
| 48 | |
| 49 /* | |
| 50 * When creating a zero-based sandbox, we do not allocate the first 64K of | |
| 51 * pages beneath the trampolines, because -- on Linux at least -- we cannot. | |
| 52 * Instead, we allocate starting at the trampolines, and then coerce the | |
| 53 * "mem" out parameter. | |
| 54 */ | |
| 55 CHECK(*mem == NULL); | |
| 56 addrsp_size -= NACL_TRAMPOLINE_START; | |
| 57 result = NaCl_page_alloc_at_addr(&tmp_mem, addrsp_size); | |
| 58 | |
| 59 if (0 != result) { | |
| 60 NaClLog(2, | |
| 61 "NaClAllocateSpace: NaCl_page_alloc_at_addr 0x%08"NACL_PRIxPTR | |
| 62 " failed\n", | |
| 63 (uintptr_t) tmp_mem); | |
| 64 return LOAD_NO_MEMORY; | |
| 65 } | |
| 66 NaClLog(4, "NaClAllocateSpace: %"NACL_PRIxPTR", %"NACL_PRIxS"\n", | |
| 67 (uintptr_t) *mem, | |
| 68 addrsp_size); | |
| 69 | |
| 70 return LOAD_OK; | |
| 71 } | |
| 72 | |
| 73 /* | |
| 74 * In the Mips sandboxing scheme we put the NaCl module at low virtual | |
| 75 * address -- and thus there can only ever be one running NaCl app per | |
| 76 * sel_ldr process -- to simplify the address masking etc needed for | |
| 77 * the sandboxing. All memory below ((uintptr_t) 1) << nap->addr_bits | |
| 78 * is accessible to the NaCl app, and modulo page protection, | |
| 79 * potentially writable. Page protection is, of course, used to | |
| 80 * prevent writing to text and rodata, including the trusted | |
| 81 * trampoline code thunks. To simplify write sandboxing, some | |
| 82 * additional guard pages outside of the address space is needed, so | |
| 83 * that we don't have to additionally check the effective address | |
| 84 * obtained by register-relative addressing modes. | |
| 85 */ | |
| 86 NaClErrorCode NaClMprotectGuards(struct NaClApp *nap) { | |
|
Mark Seaborn
2012/09/08 02:43:14
This is gone from the ARM version. Please remove
petarj
2012/09/11 16:58:13
Done.
| |
| 87 int err; | |
| 88 void *guard_base = (void *) (((uintptr_t) 1) << nap->addr_bits); | |
| 89 /* | |
| 90 * In Mips implementation kernel does not allow us to mmap address space at | |
| 91 * address 0x0, so we mmap it at the start of a trampoline region. | |
| 92 * Therefore, there is not need to mprotect at the start_addr. | |
| 93 * | |
| 94 * However, we do create a vmmap entry to describe it. | |
| 95 */ | |
| 96 NaClLog(3, | |
| 97 ("NULL detection region start 0x%08"NACL_PRIxPTR", " | |
| 98 "size 0x%08x, end 0x%08"NACL_PRIxPTR"\n"), | |
| 99 0, NACL_SYSCALL_START_ADDR, | |
| 100 NACL_SYSCALL_START_ADDR); | |
| 101 | |
| 102 NaClVmmapAdd(&nap->mem_map, | |
| 103 nap->mem_start >> NACL_PAGESHIFT, | |
| 104 NACL_SYSCALL_START_ADDR >> NACL_PAGESHIFT, | |
| 105 PROT_NONE, | |
| 106 NACL_VMMAP_ENTRY_ANONYMOUS); | |
| 107 | |
| 108 /* | |
| 109 * We need to create a two-page guard region at the base of | |
| 110 * trusted memory, for write sandboxing. | |
| 111 */ | |
| 112 NaClLog(4, "NaClMprotectGuards: %"NACL_PRIxPTR", %"NACL_PRIxS"\n", | |
| 113 (uintptr_t) guard_base, | |
| 114 (size_t) NACL_ADDRSPACE_UPPER_GUARD_SIZE); | |
| 115 if ((err = NaCl_mprotect(guard_base, | |
| 116 NACL_ADDRSPACE_UPPER_GUARD_SIZE, | |
| 117 PROT_NONE)) != 0) { | |
| 118 NaClLog(LOG_ERROR, ("NaClMemoryProtection: failed to protect lower guard " | |
| 119 "on trusted memory space (error %d)\n"), | |
| 120 err); | |
| 121 return LOAD_MPROTECT_FAIL; | |
| 122 } | |
| 123 | |
| 124 /* | |
| 125 * NB: the pages just mapped are OUTSIDE of the address space of the | |
| 126 * NaCl module. We should not track them in the Vmmap structure, | |
| 127 * since that's to track addressable memory for mapping and unmapping. | |
| 128 * | |
| 129 * This means that because these pages are implicit and not tracked, | |
| 130 * we should have a hook to tear down these pages as part of the | |
| 131 * NaClApp dtor. | |
| 132 */ | |
| 133 return LOAD_OK; | |
| 134 } | |
| OLD | NEW |