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 |