Chromium Code Reviews| 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 (mem_size = VirtualQuery((LPCVOID)start, &mem, sizeof(mem))) { | |
|
Mark Seaborn
2011/08/16 20:18:43
I wouldn't put assignments inside while() or if().
bbudge
2011/08/16 20:35:58
Done.
| |
| 46 CHECK(mem_size == sizeof(mem)); | |
| 47 | |
| 48 if (mem.State == MEM_RESERVE && | |
| 49 mem.AllocationProtect == PAGE_NOACCESS && | |
| 50 mem.RegionSize == num_bytes) { | |
| 51 if (!VirtualFree(start, 0, MEM_RELEASE)) { | |
| 52 DWORD err = GetLastError(); | |
| 53 NaClLog(LOG_FATAL, | |
| 54 "NaCl_find_prereserved_sandbox_memory: VirtualFree(0x%016" | |
|
Mark Seaborn
2011/08/16 20:18:43
Indent args to align with '('
bbudge
2011/08/16 20:35:58
Done.
| |
| 55 NACL_PRIxPTR", 0, MEM_RELEASE) failed " | |
| 56 "with error 0x%X\n", | |
| 57 (uintptr_t) start, err); | |
| 58 } | |
| 59 *p = start; | |
| 60 return 0; | |
| 61 } | |
| 62 start += mem.RegionSize; | |
| 63 if ((LPVOID)start >= sys_info.lpMaximumApplicationAddress) | |
| 64 break; | |
| 65 } | |
| 66 return -ENOMEM; | |
| 67 } | |
| 68 | |
| 69 #endif /* NACL_ARCH_CPU_32_BITS */ | |
| 70 | |
| 27 /* | 71 /* |
| 28 * NaCl_page_free: free pages allocated with NaCl_page_alloc. | 72 * NaCl_page_free: free pages allocated with NaCl_page_alloc. |
| 29 * Must start at allocation granularity (NACL_MAP_PAGESIZE) and | 73 * Must start at allocation granularity (NACL_MAP_PAGESIZE) and |
| 30 * number of bytes must be a multiple of allocation granularity. | 74 * number of bytes must be a multiple of allocation granularity. |
| 31 */ | 75 */ |
| 32 void NaCl_page_free(void *p, | 76 void NaCl_page_free(void *p, |
| 33 size_t num_bytes) { | 77 size_t num_bytes) { |
| 34 void *end_addr; | 78 void *end_addr; |
| 35 | 79 |
| 36 end_addr = (void *) (((char *) p) + num_bytes); | 80 end_addr = (void *) (((char *) p) + num_bytes); |
| 37 while (p < end_addr) { | 81 while (p < end_addr) { |
| 38 if (!VirtualFree(p, 0, MEM_RELEASE)) { | 82 if (!VirtualFree(p, 0, MEM_RELEASE)) { |
| 39 DWORD err = GetLastError(); | 83 DWORD err = GetLastError(); |
| 40 NaClLog(LOG_FATAL, | 84 NaClLog(LOG_FATAL, |
| 41 "NaCl_page_free: VirtualFree(0x%016"NACL_PRIxPTR | 85 "NaCl_page_free: VirtualFree(0x%016"NACL_PRIxPTR |
| 42 ", 0, MEM_RELEASE) failed " | 86 ", 0, MEM_RELEASE) failed " |
| 43 "with error 0x%X\n", | 87 "with error 0x%X\n", |
| 44 (uintptr_t) p, err); | 88 (uintptr_t) p, err); |
| 45 } | 89 } |
| 46 p = (void *) (((char *) p) + NACL_MAP_PAGESIZE); | 90 p = (void *) (((char *) p) + NACL_MAP_PAGESIZE); |
| 47 } | 91 } |
| 48 } | 92 } |
| 49 | 93 |
| 50 | 94 |
| 51 static | 95 int NaCl_page_alloc_at_addr(void **p, |
| 52 int NaCl_page_alloc_hint(void **p, | |
| 53 size_t num_bytes) { | 96 size_t num_bytes) { |
| 54 SYSTEM_INFO sys_info; | 97 SYSTEM_INFO sys_info; |
| 55 | 98 |
| 56 int attempt_count; | 99 int attempt_count; |
| 57 | 100 |
| 58 void *hint = *p; | 101 void *hint = *p; |
| 59 void *addr; | 102 void *addr; |
| 60 void *end_addr; | 103 void *end_addr; |
| 61 void *chunk; | 104 void *chunk; |
| 62 void *unroll; | 105 void *unroll; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 /* double break */ | 187 /* double break */ |
| 145 } | 188 } |
| 146 } | 189 } |
| 147 NaClLog(2, | 190 NaClLog(2, |
| 148 ("NaCl_page_alloc: *p = 0x%016"NACL_PRIxPTR"," | 191 ("NaCl_page_alloc: *p = 0x%016"NACL_PRIxPTR"," |
| 149 " returning success.\n"), | 192 " returning success.\n"), |
| 150 (uintptr_t) addr); | 193 (uintptr_t) addr); |
| 151 *p = addr; | 194 *p = addr; |
| 152 return 0; | 195 return 0; |
| 153 retry: | 196 retry: |
| 154 NaClLog(2, "NaCl_page_alloc_hint: retrying w/o hint\n"); | 197 NaClLog(2, "NaCl_page_alloc_at_addr: retrying w/o hint\n"); |
| 155 hint = NULL; | 198 hint = NULL; |
| 156 } | 199 } |
| 157 | 200 |
| 158 return -ENOMEM; | 201 return -ENOMEM; |
| 159 } | 202 } |
| 160 | 203 |
| 161 int NaCl_page_alloc(void **p, | 204 int NaCl_page_alloc(void **p, |
| 162 size_t num_bytes) { | 205 size_t num_bytes) { |
| 163 *p = NULL; | 206 *p = NULL; |
| 164 return NaCl_page_alloc_hint(p, num_bytes); | 207 return NaCl_page_alloc_at_addr(p, num_bytes); |
| 165 } | 208 } |
| 166 | 209 |
| 167 /* | 210 /* |
| 168 * Pick a "hint" address that is random. | 211 * Pick a "hint" address that is random. |
| 169 */ | 212 */ |
| 170 int NaCl_page_alloc_randomized(void **p, | 213 int NaCl_page_alloc_randomized(void **p, |
| 171 size_t size) { | 214 size_t size) { |
| 172 uintptr_t addr; | 215 uintptr_t addr; |
| 173 int neg_errno = -ENOMEM; /* in case we change kNumTries to 0 */ | 216 int neg_errno = -ENOMEM; /* in case we change kNumTries to 0 */ |
| 174 int tries; | 217 int tries; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 196 * bits of entropy. | 239 * bits of entropy. |
| 197 */ | 240 */ |
| 198 *p = (void *) ((addr << NACL_MAP_PAGESHIFT) /* bits [47:16] are random */ | 241 *p = (void *) ((addr << NACL_MAP_PAGESHIFT) /* bits [47:16] are random */ |
| 199 & ((((uintptr_t) 1) << 43) - 1)); /* now bits [42:16] */ | 242 & ((((uintptr_t) 1) << 43) - 1)); /* now bits [42:16] */ |
| 200 #else | 243 #else |
| 201 # error "where am i?" | 244 # error "where am i?" |
| 202 #endif | 245 #endif |
| 203 | 246 |
| 204 NaClLog(LOG_INFO, "NaCl_page_alloc_randomized: hint 0x%"NACL_PRIxPTR"\n", | 247 NaClLog(LOG_INFO, "NaCl_page_alloc_randomized: hint 0x%"NACL_PRIxPTR"\n", |
| 205 (uintptr_t) *p); | 248 (uintptr_t) *p); |
| 206 neg_errno = NaCl_page_alloc_hint(p, size); | 249 neg_errno = NaCl_page_alloc_at_addr(p, size); |
| 207 if (0 == neg_errno) { | 250 if (0 == neg_errno) { |
| 208 break; | 251 break; |
| 209 } | 252 } |
| 210 } | 253 } |
| 211 if (0 != neg_errno) { | 254 if (0 != neg_errno) { |
| 212 NaClLog(LOG_INFO, | 255 NaClLog(LOG_INFO, |
| 213 "NaCl_page_alloc_randomized: failed (%d), dropping hints\n", | 256 "NaCl_page_alloc_randomized: failed (%d), dropping hints\n", |
| 214 -neg_errno); | 257 -neg_errno); |
| 215 *p = 0; | 258 *p = 0; |
| 216 neg_errno = NaCl_page_alloc_hint(p, size); | 259 neg_errno = NaCl_page_alloc_at_addr(p, size); |
| 217 } | 260 } |
| 218 return neg_errno; | 261 return neg_errno; |
| 219 } | 262 } |
| 220 | 263 |
| 221 uintptr_t NaClProtectChunkSize(uintptr_t start, | 264 uintptr_t NaClProtectChunkSize(uintptr_t start, |
| 222 uintptr_t end) { | 265 uintptr_t end) { |
| 223 uintptr_t chunk_end; | 266 uintptr_t chunk_end; |
| 224 | 267 |
| 225 chunk_end = NaClRoundAllocPage(start + 1); | 268 chunk_end = NaClRoundAllocPage(start + 1); |
| 226 if (chunk_end > end) { | 269 if (chunk_end > end) { |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 break; | 442 break; |
| 400 case MADV_NORMAL: | 443 case MADV_NORMAL: |
| 401 memset(start, 0, length); | 444 memset(start, 0, length); |
| 402 break; | 445 break; |
| 403 default: | 446 default: |
| 404 return -EINVAL; | 447 return -EINVAL; |
| 405 } | 448 } |
| 406 NaClLog(2, "NaCl_madvise: done\n"); | 449 NaClLog(2, "NaCl_madvise: done\n"); |
| 407 return 0; | 450 return 0; |
| 408 } | 451 } |
| OLD | NEW |