Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(322)

Side by Side Diff: src/trusted/service_runtime/sel_ldr_standard.c

Issue 4181005: Fixes some bugs with memory setup and halt-sled allocation and... (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/trusted/service_runtime/sel_ldr.c ('k') | tools/command_tester.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2008 The Native Client Authors. All rights reserved. 2 * Copyright 2008 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can 3 * Use of this source code is governed by a BSD-style license that can
4 * be found in the LICENSE file. 4 * be found in the LICENSE file.
5 */ 5 */
6 6
7 /* 7 /*
8 * NaCl Simple/secure ELF loader (NaCl SEL). 8 * NaCl Simple/secure ELF loader (NaCl SEL).
9 */ 9 */
10 10
(...skipping 26 matching lines...) Expand all
37 #include "native_client/src/trusted/service_runtime/sel_addrspace.h" 37 #include "native_client/src/trusted/service_runtime/sel_addrspace.h"
38 #include "native_client/src/trusted/service_runtime/win/mman.h" 38 #include "native_client/src/trusted/service_runtime/win/mman.h"
39 39
40 #if !defined(SIZE_T_MAX) 40 #if !defined(SIZE_T_MAX)
41 # define SIZE_T_MAX (~(size_t) 0) 41 # define SIZE_T_MAX (~(size_t) 0)
42 #endif 42 #endif
43 43
44 44
45 /* 45 /*
46 * Fill from static_text_end to end of that page with halt 46 * Fill from static_text_end to end of that page with halt
47 * instruction, which is NACL_HALT_LEN in size. Does not touch 47 * instruction, which is at least NACL_HALT_LEN in size when no
48 * dynamic text region, which should be pre-filled with HLTs. 48 * dynamic text is present. Does not touch dynamic text region, which
49 * should be pre-filled with HLTs.
50 *
51 * By adding NACL_HALT_SLED_SIZE, we ensure that the code region ends
52 * with HLTs, just in case the CPU has a bug in which it fails to
53 * check for running off the end of the x86 code segment.
49 */ 54 */
50 void NaClFillEndOfTextRegion(struct NaClApp *nap) { 55 void NaClFillEndOfTextRegion(struct NaClApp *nap) {
51 size_t page_pad; 56 size_t page_pad;
52 57
53 /* 58 /*
54 * By adding NACL_HALT_SLED_SIZE, we ensure that the code region 59 * NOTE: make sure we are not silently overwriting data. It is the
55 * ends with HLTs, just in case the CPU has a bug in which it fails 60 * toolchain's responsibility to ensure that a NACL_HALT_SLED_SIZE
56 * to check for running off the end of the x86 code segment. 61 * gap exists.
57 */ 62 */
58 page_pad = (NaClRoundAllocPage(nap->static_text_end + NACL_HALT_SLED_SIZE)
59 - nap->static_text_end);
60
61 /* NOTE: make sure we are not silently overwriting data */
62 if (0 != nap->data_start && 63 if (0 != nap->data_start &&
63 nap->static_text_end + NACL_HALT_SLED_SIZE > nap->data_start) { 64 nap->static_text_end + NACL_HALT_SLED_SIZE > nap->data_start) {
64 NaClLog(LOG_FATAL, "Missing gap between text and data for halt_sled"); 65 NaClLog(LOG_FATAL, "Missing gap between text and data for halt_sled\n");
65 } 66 }
66 if (0 != nap->rodata_start && 67 if (0 != nap->rodata_start &&
67 nap->static_text_end + NACL_HALT_SLED_SIZE > nap->rodata_start) { 68 nap->static_text_end + NACL_HALT_SLED_SIZE > nap->rodata_start) {
68 NaClLog(LOG_FATAL, "Missing gap between text and rodata for halt_sled"); 69 NaClLog(LOG_FATAL, "Missing gap between text and rodata for halt_sled\n");
69 } 70 }
70 71
71 CHECK(page_pad >= NACL_HALT_SLED_SIZE); 72 if (NULL == nap->text_shm) {
72 CHECK(page_pad < NACL_MAP_PAGESIZE + NACL_HALT_SLED_SIZE); 73 /*
74 * No dynamic text exists. Space for NACL_HALT_SLED_SIZE must
75 * exist.
76 */
77 page_pad = (NaClRoundAllocPage(nap->static_text_end + NACL_HALT_SLED_SIZE)
78 - nap->static_text_end);
79 CHECK(page_pad >= NACL_HALT_SLED_SIZE);
80 CHECK(page_pad < NACL_MAP_PAGESIZE + NACL_HALT_SLED_SIZE);
81 } else {
82 /*
83 * Dynamic text exists; the halt sled resides in the dynamic text
84 * region, so all we need to do here is to round out the last
85 * static text page with HLT instructions. It doesn't matter if
86 * the size of this region is smaller than NACL_HALT_SLED_SIZE --
87 * this is just to fully initialize the page, rather than (later)
88 * decoding/validating zero-filled memory as instructions.
89 */
90 page_pad = NaClRoundAllocPage(nap->static_text_end) - nap->static_text_end;
91 }
73 92
74 NaClLog(4, 93 NaClLog(4,
75 "Filling with halts: %08"NACL_PRIxPTR", %08"NACL_PRIxS" bytes\n", 94 "Filling with halts: %08"NACL_PRIxPTR", %08"NACL_PRIxS" bytes\n",
76 nap->mem_start + nap->static_text_end, 95 nap->mem_start + nap->static_text_end,
77 page_pad); 96 page_pad);
78 97
79 NaClFillMemoryRegionWithHalt((void *)(nap->mem_start + nap->static_text_end), 98 NaClFillMemoryRegionWithHalt((void *)(nap->mem_start + nap->static_text_end),
80 page_pad); 99 page_pad);
81 100
82 nap->static_text_end += page_pad; 101 nap->static_text_end += page_pad;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 &nap->rodata_start, 150 &nap->rodata_start,
132 &rodata_end, 151 &rodata_end,
133 &nap->data_start, 152 &nap->data_start,
134 &data_end, 153 &data_end,
135 &max_vaddr); 154 &max_vaddr);
136 if (LOAD_OK != subret) { 155 if (LOAD_OK != subret) {
137 ret = subret; 156 ret = subret;
138 goto done; 157 goto done;
139 } 158 }
140 159
160 if (0 == nap->data_start) {
161 if (0 == nap->rodata_start) {
162 if (NaClRoundAllocPage(max_vaddr) - max_vaddr < NACL_HALT_SLED_SIZE) {
163 /*
164 * if no rodata and no data, we make sure that there is space for
165 * the halt sled.
166 */
167 max_vaddr += NACL_MAP_PAGESIZE;
168 }
169 } else {
170 /*
171 * no data, but there is rodata. this means max_vaddr is just
172 * where rodata ends. this might not be at an allocation
173 * boundary, and in this the page would not be writable. round
174 * max_vaddr up to the next allocation boundary so that bss will
175 * be at the next writable region.
176 */
177 ;
178 }
179 max_vaddr = NaClRoundAllocPage(max_vaddr);
180 }
181 /*
182 * max_vaddr -- the break or the boundary between data (initialized
183 * and bss) and the address space hole -- does not have to be at a
184 * page boundary.
185 */
141 nap->break_addr = max_vaddr; 186 nap->break_addr = max_vaddr;
142 nap->data_end = max_vaddr; 187 nap->data_end = max_vaddr;
143 188
144 NaClLog(4, "rodata_end = %08"NACL_PRIxPTR"\n", rodata_end); 189 NaClLog(4, "Values from NaClElfImageValidateProgramHeaders:\n");
145 NaClLog(4, "data_start = %08"NACL_PRIxPTR"\n", nap->data_start); 190 NaClLog(4, "rodata_start = 0x%08"NACL_PRIxPTR"\n", nap->rodata_start);
146 NaClLog(4, "data_end = %08"NACL_PRIxPTR"\n", data_end); 191 NaClLog(4, "rodata_end = 0x%08"NACL_PRIxPTR"\n", rodata_end);
147 NaClLog(4, "max_vaddr = %08"NACL_PRIxPTR"\n", max_vaddr); 192 NaClLog(4, "data_start = 0x%08"NACL_PRIxPTR"\n", nap->data_start);
193 NaClLog(4, "data_end = 0x%08"NACL_PRIxPTR"\n", data_end);
194 NaClLog(4, "max_vaddr = 0x%08"NACL_PRIxPTR"\n", max_vaddr);
148 195
149 #if 0 == NACL_DANGEROUS_DEBUG_MODE_DISABLE_INNER_SANDBOX 196 #if 0 == NACL_DANGEROUS_DEBUG_MODE_DISABLE_INNER_SANDBOX
150 nap->bundle_size = NaClElfImageGetBundleSize(image); 197 nap->bundle_size = NaClElfImageGetBundleSize(image);
151 if (nap->bundle_size == 0) { 198 if (nap->bundle_size == 0) {
152 ret = LOAD_BAD_ABI; 199 ret = LOAD_BAD_ABI;
153 goto done; 200 goto done;
154 } 201 }
155 #else 202 #else
156 /* pick some reasonable default for an un-sandboxed nexe */ 203 /* pick some reasonable default for an un-sandboxed nexe */
157 nap->bundle_size = 32; 204 nap->bundle_size = 32;
158 #endif 205 #endif
159 nap->entry_pt = NaClElfImageGetEntryPoint(image); 206 nap->entry_pt = NaClElfImageGetEntryPoint(image);
160 207
161 NaClLog(2, 208 NaClLog(2,
162 "static_text_end: 0x%016"NACL_PRIxPTR" " 209 "NaClApp addr space layout:\n");
163 "break_add: 0x%016"NACL_PRIxPTR" " 210 NaClLog(2,
164 "data_end: 0x%016"NACL_PRIxPTR" " 211 "nap->static_text_end = 0x%016"NACL_PRIxPTR"\n",
165 "entry_pt: 0x%016"NACL_PRIxPTR" " 212 nap->static_text_end);
166 "bundle_size: 0x%x\n", 213 NaClLog(2,
167 nap->static_text_end, 214 "nap->dynamic_text_start = 0x%016"NACL_PRIxPTR"\n",
168 nap->break_addr, 215 nap->dynamic_text_start);
169 nap->data_end, 216 NaClLog(2,
170 nap->entry_pt, 217 "nap->dynamic_text_end = 0x%016"NACL_PRIxPTR"\n",
218 nap->dynamic_text_end);
219 NaClLog(2,
220 "nap->rodata_start = 0x%016"NACL_PRIxPTR"\n",
221 nap->rodata_start);
222 NaClLog(2,
223 "nap->data_start = 0x%016"NACL_PRIxPTR"\n",
224 nap->data_start);
225 NaClLog(2,
226 "nap->data_end = 0x%016"NACL_PRIxPTR"\n",
227 nap->data_end);
228 NaClLog(2,
229 "nap->break_addr = 0x%016"NACL_PRIxPTR"\n",
230 nap->break_addr);
231 NaClLog(2,
232 "nap->entry_pt = 0x%016"NACL_PRIxPTR"\n",
233 nap->entry_pt);
234 NaClLog(2,
235 "nap->bundle_size = 0x%x\n",
171 nap->bundle_size); 236 nap->bundle_size);
172 237
173 if (!NaClAddrIsValidEntryPt(nap, nap->entry_pt)) { 238 if (!NaClAddrIsValidEntryPt(nap, nap->entry_pt)) {
174 ret = LOAD_BAD_ENTRY; 239 ret = LOAD_BAD_ENTRY;
175 goto done; 240 goto done;
176 } 241 }
177 242
178 /* 243 /*
179 * Basic address space layout sanity check. 244 * Basic address space layout sanity check.
180 */ 245 */
181 if (0 != nap->data_start) { 246 if (0 != nap->data_start) {
182 if (data_end != max_vaddr) { 247 if (data_end != max_vaddr) {
183 NaClLog(LOG_INFO, "data segment is not last\n"); 248 NaClLog(LOG_INFO, "data segment is not last\n");
184 ret = LOAD_DATA_NOT_LAST_SEGMENT; 249 ret = LOAD_DATA_NOT_LAST_SEGMENT;
185 goto done; 250 goto done;
186 } 251 }
187 } else if (0 != nap->rodata_start) { 252 } else if (0 != nap->rodata_start) {
188 if (rodata_end != max_vaddr) { 253 if (NaClRoundAllocPage(rodata_end) != max_vaddr) {
189 /* 254 /*
190 * This should be unreachable, but we include it just for 255 * This should be unreachable, but we include it just for
191 * completeness. 256 * completeness.
192 * 257 *
193 * Here is why it is unreachable: 258 * Here is why it is unreachable:
194 * 259 *
195 * NaClPhdrChecks checks the test segment starting address. The 260 * NaClPhdrChecks checks the test segment starting address. The
196 * only allowed loaded segments are text, data, and rodata. 261 * only allowed loaded segments are text, data, and rodata.
197 * Thus unless the rodata is in the trampoline region, it must 262 * Thus unless the rodata is in the trampoline region, it must
198 * be after the text. And NaClElfImageValidateProgramHeaders 263 * be after the text. And NaClElfImageValidateProgramHeaders
(...skipping 16 matching lines...) Expand all
215 ret = LOAD_TEXT_OVERLAPS_RODATA; 280 ret = LOAD_TEXT_OVERLAPS_RODATA;
216 goto done; 281 goto done;
217 } 282 }
218 } else if (0 != nap->data_start) { 283 } else if (0 != nap->data_start) {
219 if (NaClRoundAllocPage(NaClEndOfStaticText(nap)) > nap->data_start) { 284 if (NaClRoundAllocPage(NaClEndOfStaticText(nap)) > nap->data_start) {
220 ret = LOAD_TEXT_OVERLAPS_DATA; 285 ret = LOAD_TEXT_OVERLAPS_DATA;
221 goto done; 286 goto done;
222 } 287 }
223 } 288 }
224 289
290 if (0 != nap->rodata_start &&
291 NaClRoundAllocPage(nap->rodata_start) != nap->rodata_start) {
292 NaClLog(LOG_INFO, "rodata_start not a multiple of allocation size\n");
293 ret = LOAD_BAD_RODATA_ALIGNMENT;
294 goto done;
295 }
296 if (0 != nap->data_start &&
297 NaClRoundAllocPage(nap->data_start) != nap->data_start) {
298 NaClLog(LOG_INFO, "data_start not a multiple of allocation size\n");
299 ret = LOAD_BAD_DATA_ALIGNMENT;
300 goto done;
301 }
302
225 NaClLog(2, "Allocating address space\n"); 303 NaClLog(2, "Allocating address space\n");
226 subret = NaClAllocAddrSpace(nap); 304 subret = NaClAllocAddrSpace(nap);
227 if (LOAD_OK != subret) { 305 if (LOAD_OK != subret) {
228 ret = subret; 306 ret = subret;
229 goto done; 307 goto done;
230 } 308 }
231 309
232 /* 310 /*
233 * NB: mem_map object has been initialized, but is empty. 311 * NB: mem_map object has been initialized, but is empty.
234 * NaClMakeDynamicTextShared does not touch it. 312 * NaClMakeDynamicTextShared does not touch it.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 * about the memory pages and their current protection value. 385 * about the memory pages and their current protection value.
308 * 386 *
309 * The contents of the dynamic text region will get remapped as 387 * The contents of the dynamic text region will get remapped as
310 * non-writable. 388 * non-writable.
311 */ 389 */
312 subret = NaClMemoryProtection(nap); 390 subret = NaClMemoryProtection(nap);
313 if (LOAD_OK != subret) { 391 if (LOAD_OK != subret) {
314 ret = subret; 392 ret = subret;
315 goto done; 393 goto done;
316 } 394 }
395 NaClLog(2,
396 "NaClAppLoadFile done; addr space layout:\n");
397 NaClLog(2,
398 "nap->static_text_end = 0x%016"NACL_PRIxPTR"\n",
399 nap->static_text_end);
400 NaClLog(2,
401 "nap->dynamic_text_start = 0x%016"NACL_PRIxPTR"\n",
402 nap->dynamic_text_start);
403 NaClLog(2,
404 "nap->dynamic_text_end = 0x%016"NACL_PRIxPTR"\n",
405 nap->dynamic_text_end);
406 NaClLog(2,
407 "nap->rodata_start = 0x%016"NACL_PRIxPTR"\n",
408 nap->rodata_start);
409 NaClLog(2,
410 "nap->data_start = 0x%016"NACL_PRIxPTR"\n",
411 nap->data_start);
412 NaClLog(2,
413 "nap->data_end = 0x%016"NACL_PRIxPTR"\n",
414 nap->data_end);
415 NaClLog(2,
416 "nap->break_addr = 0x%016"NACL_PRIxPTR"\n",
417 nap->break_addr);
418 NaClLog(2,
419 "nap->entry_pt = 0x%016"NACL_PRIxPTR"\n",
420 nap->entry_pt);
421 NaClLog(2,
422 "nap->bundle_size = 0x%x\n",
423 nap->bundle_size);
317 424
318 ret = LOAD_OK; 425 ret = LOAD_OK;
319 done: 426 done:
320 NaClElfImageDelete(image); 427 NaClElfImageDelete(image);
321 return ret; 428 return ret;
322 } 429 }
323 430
324 int NaClAddrIsValidEntryPt(struct NaClApp *nap, 431 int NaClAddrIsValidEntryPt(struct NaClApp *nap,
325 uintptr_t addr) { 432 uintptr_t addr) {
326 if (0 != (addr & (nap->bundle_size - 1))) { 433 if (0 != (addr & (nap->bundle_size - 1))) {
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 sys_tdb, 703 sys_tdb,
597 tdb_size)) { 704 tdb_size)) {
598 NaClLog(LOG_WARNING, 705 NaClLog(LOG_WARNING,
599 ("NaClCreateAdditionalThread: could not allocate thread index." 706 ("NaClCreateAdditionalThread: could not allocate thread index."
600 " Returning EAGAIN per POSIX specs.\n")); 707 " Returning EAGAIN per POSIX specs.\n"));
601 free(natp); 708 free(natp);
602 return -NACL_ABI_EAGAIN; 709 return -NACL_ABI_EAGAIN;
603 } 710 }
604 return 0; 711 return 0;
605 } 712 }
OLDNEW
« no previous file with comments | « src/trusted/service_runtime/sel_ldr.c ('k') | tools/command_tester.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698