OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 /* | 7 /* |
8 * NaCl Service Runtime memory allocation code | 8 * NaCl Service Runtime memory allocation code |
9 */ | 9 */ |
10 #include "native_client/src/include/portability.h" | 10 #include "native_client/src/include/portability.h" |
11 #include "native_client/src/include/win/mman.h" | 11 #include "native_client/src/include/win/mman.h" |
12 | 12 |
13 #include <errno.h> | 13 #include <errno.h> |
14 #include <windows.h> | 14 #include <windows.h> |
15 #include <string.h> | 15 #include <string.h> |
16 | 16 |
| 17 #include "native_client/src/shared/platform/nacl_check.h" |
17 #include "native_client/src/shared/platform/nacl_global_secure_random.h" | 18 #include "native_client/src/shared/platform/nacl_global_secure_random.h" |
18 #include "native_client/src/shared/platform/nacl_log.h" | 19 #include "native_client/src/shared/platform/nacl_log.h" |
19 #include "native_client/src/shared/platform/win/xlate_system_error.h" | 20 #include "native_client/src/shared/platform/win/xlate_system_error.h" |
20 | 21 |
21 #include "native_client/src/trusted/service_runtime/nacl_config.h" | 22 #include "native_client/src/trusted/service_runtime/nacl_config.h" |
22 #include "native_client/src/trusted/service_runtime/sel_memory.h" | 23 #include "native_client/src/trusted/service_runtime/sel_memory.h" |
23 #include "native_client/src/trusted/service_runtime/sel_util.h" | 24 #include "native_client/src/trusted/service_runtime/sel_util.h" |
24 | 25 |
25 #define MSGWIDTH "25" | 26 #define MSGWIDTH "25" |
26 | 27 |
| 28 #if NACL_BUILD_SUBARCH == 32 |
| 29 |
| 30 /* |
| 31 * This function searches for sandbox memory that has been reserved by |
| 32 * the parent process on our behalf. We pre-reserve the sandbox on 32-bit |
| 33 * systems because otherwise the address space may become fragmented, making |
| 34 * the large sandbox request fail. |
| 35 */ |
| 36 int NaCl_find_prereserved_sandbox_memory(void **p, |
| 37 size_t num_bytes) { |
| 38 SYSTEM_INFO sys_info; |
| 39 MEMORY_BASIC_INFORMATION mem; |
| 40 char *start; |
| 41 SIZE_T mem_size; |
| 42 |
| 43 GetSystemInfo(&sys_info); |
| 44 start = sys_info.lpMinimumApplicationAddress; |
| 45 while (1) { |
| 46 mem_size = VirtualQuery((LPCVOID)start, &mem, sizeof(mem)); |
| 47 if (mem_size == 0) |
| 48 break; |
| 49 CHECK(mem_size == sizeof(mem)); |
| 50 |
| 51 if (mem.State == MEM_RESERVE && |
| 52 mem.AllocationProtect == PAGE_NOACCESS && |
| 53 mem.RegionSize == num_bytes) { |
| 54 if (!VirtualFree(start, 0, MEM_RELEASE)) { |
| 55 DWORD err = GetLastError(); |
| 56 NaClLog(LOG_FATAL, |
| 57 "NaCl_find_prereserved_sandbox_memory: VirtualFree(0x%016" |
| 58 NACL_PRIxPTR", 0, MEM_RELEASE) failed " |
| 59 "with error 0x%X\n", |
| 60 (uintptr_t) start, err); |
| 61 } |
| 62 *p = start; |
| 63 return 0; |
| 64 } |
| 65 start += mem.RegionSize; |
| 66 if ((LPVOID)start >= sys_info.lpMaximumApplicationAddress) |
| 67 break; |
| 68 } |
| 69 return -ENOMEM; |
| 70 } |
| 71 |
| 72 #endif /* NACL_ARCH_CPU_32_BITS */ |
| 73 |
27 /* | 74 /* |
28 * NaCl_page_free: free pages allocated with NaCl_page_alloc. | 75 * NaCl_page_free: free pages allocated with NaCl_page_alloc. |
29 * Must start at allocation granularity (NACL_MAP_PAGESIZE) and | 76 * Must start at allocation granularity (NACL_MAP_PAGESIZE) and |
30 * number of bytes must be a multiple of allocation granularity. | 77 * number of bytes must be a multiple of allocation granularity. |
31 */ | 78 */ |
32 void NaCl_page_free(void *p, | 79 void NaCl_page_free(void *p, |
33 size_t num_bytes) { | 80 size_t num_bytes) { |
34 void *end_addr; | 81 void *end_addr; |
35 | 82 |
36 end_addr = (void *) (((char *) p) + num_bytes); | 83 end_addr = (void *) (((char *) p) + num_bytes); |
37 while (p < end_addr) { | 84 while (p < end_addr) { |
38 if (!VirtualFree(p, 0, MEM_RELEASE)) { | 85 if (!VirtualFree(p, 0, MEM_RELEASE)) { |
39 DWORD err = GetLastError(); | 86 DWORD err = GetLastError(); |
40 NaClLog(LOG_FATAL, | 87 NaClLog(LOG_FATAL, |
41 "NaCl_page_free: VirtualFree(0x%016"NACL_PRIxPTR | 88 "NaCl_page_free: VirtualFree(0x%016"NACL_PRIxPTR |
42 ", 0, MEM_RELEASE) failed " | 89 ", 0, MEM_RELEASE) failed " |
43 "with error 0x%X\n", | 90 "with error 0x%X\n", |
44 (uintptr_t) p, err); | 91 (uintptr_t) p, err); |
45 } | 92 } |
46 p = (void *) (((char *) p) + NACL_MAP_PAGESIZE); | 93 p = (void *) (((char *) p) + NACL_MAP_PAGESIZE); |
47 } | 94 } |
48 } | 95 } |
49 | 96 |
50 | 97 |
51 static | 98 int NaCl_page_alloc_at_addr(void **p, |
52 int NaCl_page_alloc_hint(void **p, | |
53 size_t num_bytes) { | 99 size_t num_bytes) { |
54 SYSTEM_INFO sys_info; | 100 SYSTEM_INFO sys_info; |
55 | 101 |
56 int attempt_count; | 102 int attempt_count; |
57 | 103 |
58 void *hint = *p; | 104 void *hint = *p; |
59 void *addr; | 105 void *addr; |
60 void *end_addr; | 106 void *end_addr; |
61 void *chunk; | 107 void *chunk; |
62 void *unroll; | 108 void *unroll; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 /* double break */ | 190 /* double break */ |
145 } | 191 } |
146 } | 192 } |
147 NaClLog(2, | 193 NaClLog(2, |
148 ("NaCl_page_alloc: *p = 0x%016"NACL_PRIxPTR"," | 194 ("NaCl_page_alloc: *p = 0x%016"NACL_PRIxPTR"," |
149 " returning success.\n"), | 195 " returning success.\n"), |
150 (uintptr_t) addr); | 196 (uintptr_t) addr); |
151 *p = addr; | 197 *p = addr; |
152 return 0; | 198 return 0; |
153 retry: | 199 retry: |
154 NaClLog(2, "NaCl_page_alloc_hint: retrying w/o hint\n"); | 200 NaClLog(2, "NaCl_page_alloc_at_addr: retrying w/o hint\n"); |
155 hint = NULL; | 201 hint = NULL; |
156 } | 202 } |
157 | 203 |
158 return -ENOMEM; | 204 return -ENOMEM; |
159 } | 205 } |
160 | 206 |
161 int NaCl_page_alloc(void **p, | 207 int NaCl_page_alloc(void **p, |
162 size_t num_bytes) { | 208 size_t num_bytes) { |
163 *p = NULL; | 209 *p = NULL; |
164 return NaCl_page_alloc_hint(p, num_bytes); | 210 return NaCl_page_alloc_at_addr(p, num_bytes); |
165 } | 211 } |
166 | 212 |
167 /* | 213 /* |
168 * Pick a "hint" address that is random. | 214 * Pick a "hint" address that is random. |
169 */ | 215 */ |
170 int NaCl_page_alloc_randomized(void **p, | 216 int NaCl_page_alloc_randomized(void **p, |
171 size_t size) { | 217 size_t size) { |
172 uintptr_t addr; | 218 uintptr_t addr; |
173 int neg_errno = -ENOMEM; /* in case we change kNumTries to 0 */ | 219 int neg_errno = -ENOMEM; /* in case we change kNumTries to 0 */ |
174 int tries; | 220 int tries; |
(...skipping 21 matching lines...) Expand all Loading... |
196 * bits of entropy. | 242 * bits of entropy. |
197 */ | 243 */ |
198 *p = (void *) ((addr << NACL_MAP_PAGESHIFT) /* bits [47:16] are random */ | 244 *p = (void *) ((addr << NACL_MAP_PAGESHIFT) /* bits [47:16] are random */ |
199 & ((((uintptr_t) 1) << 43) - 1)); /* now bits [42:16] */ | 245 & ((((uintptr_t) 1) << 43) - 1)); /* now bits [42:16] */ |
200 #else | 246 #else |
201 # error "where am i?" | 247 # error "where am i?" |
202 #endif | 248 #endif |
203 | 249 |
204 NaClLog(LOG_INFO, "NaCl_page_alloc_randomized: hint 0x%"NACL_PRIxPTR"\n", | 250 NaClLog(LOG_INFO, "NaCl_page_alloc_randomized: hint 0x%"NACL_PRIxPTR"\n", |
205 (uintptr_t) *p); | 251 (uintptr_t) *p); |
206 neg_errno = NaCl_page_alloc_hint(p, size); | 252 neg_errno = NaCl_page_alloc_at_addr(p, size); |
207 if (0 == neg_errno) { | 253 if (0 == neg_errno) { |
208 break; | 254 break; |
209 } | 255 } |
210 } | 256 } |
211 if (0 != neg_errno) { | 257 if (0 != neg_errno) { |
212 NaClLog(LOG_INFO, | 258 NaClLog(LOG_INFO, |
213 "NaCl_page_alloc_randomized: failed (%d), dropping hints\n", | 259 "NaCl_page_alloc_randomized: failed (%d), dropping hints\n", |
214 -neg_errno); | 260 -neg_errno); |
215 *p = 0; | 261 *p = 0; |
216 neg_errno = NaCl_page_alloc_hint(p, size); | 262 neg_errno = NaCl_page_alloc_at_addr(p, size); |
217 } | 263 } |
218 return neg_errno; | 264 return neg_errno; |
219 } | 265 } |
220 | 266 |
221 uintptr_t NaClProtectChunkSize(uintptr_t start, | 267 uintptr_t NaClProtectChunkSize(uintptr_t start, |
222 uintptr_t end) { | 268 uintptr_t end) { |
223 uintptr_t chunk_end; | 269 uintptr_t chunk_end; |
224 | 270 |
225 chunk_end = NaClRoundAllocPage(start + 1); | 271 chunk_end = NaClRoundAllocPage(start + 1); |
226 if (chunk_end > end) { | 272 if (chunk_end > end) { |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 break; | 445 break; |
400 case MADV_NORMAL: | 446 case MADV_NORMAL: |
401 memset(start, 0, length); | 447 memset(start, 0, length); |
402 break; | 448 break; |
403 default: | 449 default: |
404 return -EINVAL; | 450 return -EINVAL; |
405 } | 451 } |
406 NaClLog(2, "NaCl_madvise: done\n"); | 452 NaClLog(2, "NaCl_madvise: done\n"); |
407 return 0; | 453 return 0; |
408 } | 454 } |
OLD | NEW |