OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2008, Google Inc. | 2 * Copyright 2008, Google Inc. |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 18 matching lines...) Expand all Loading... |
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 */ | 30 */ |
31 | 31 |
32 /* | 32 /* |
33 * NaCl Simple/secure ELF loader (NaCl SEL). | 33 * NaCl Simple/secure ELF loader (NaCl SEL). |
34 */ | 34 */ |
35 | 35 |
36 #include "native_client/src/include/portability.h" | 36 #include "native_client/src/include/portability.h" |
37 | 37 |
38 #include <stdio.h> | 38 #include <stdio.h> |
39 | |
40 #include <stdlib.h> | 39 #include <stdlib.h> |
41 #include <string.h> | 40 #include <string.h> |
42 | 41 |
43 #include "native_client/src/include/elf_constants.h" | 42 #include "native_client/src/include/elf_constants.h" |
44 #include "native_client/src/include/nacl_elf.h" | 43 #include "native_client/src/include/nacl_elf.h" |
45 #include "native_client/src/include/nacl_macros.h" | 44 #include "native_client/src/include/nacl_macros.h" |
46 #include "native_client/src/shared/platform/nacl_sync_checked.h" | 45 #include "native_client/src/shared/platform/nacl_sync_checked.h" |
47 #include "native_client/src/shared/platform/nacl_time.h" | 46 #include "native_client/src/shared/platform/nacl_time.h" |
48 | 47 |
49 #include "native_client/src/trusted/service_runtime/include/sys/errno.h" | 48 #include "native_client/src/trusted/service_runtime/include/sys/errno.h" |
50 | 49 |
51 #include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h" | 50 #include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h" |
| 51 #include "native_client/src/trusted/service_runtime/elf_util.h" |
52 #include "native_client/src/trusted/service_runtime/nacl_app_thread.h" | 52 #include "native_client/src/trusted/service_runtime/nacl_app_thread.h" |
53 #include "native_client/src/trusted/service_runtime/nacl_check.h" | 53 #include "native_client/src/trusted/service_runtime/nacl_check.h" |
54 #include "native_client/src/trusted/service_runtime/nacl_closure.h" | 54 #include "native_client/src/trusted/service_runtime/nacl_closure.h" |
55 #include "native_client/src/trusted/service_runtime/nacl_sync_queue.h" | 55 #include "native_client/src/trusted/service_runtime/nacl_sync_queue.h" |
56 #include "native_client/src/trusted/service_runtime/sel_memory.h" | 56 #include "native_client/src/trusted/service_runtime/sel_memory.h" |
57 #include "native_client/src/trusted/service_runtime/sel_ldr.h" | 57 #include "native_client/src/trusted/service_runtime/sel_ldr.h" |
58 #include "native_client/src/trusted/service_runtime/sel_util.h" | 58 #include "native_client/src/trusted/service_runtime/sel_util.h" |
59 #include "native_client/src/trusted/service_runtime/sel_addrspace.h" | 59 #include "native_client/src/trusted/service_runtime/sel_addrspace.h" |
60 #include "native_client/src/trusted/service_runtime/tramp.h" | 60 #include "native_client/src/trusted/service_runtime/tramp.h" |
61 | 61 |
62 #define PTR_ALIGN_MASK ((sizeof(void *))-1) | 62 #define PTR_ALIGN_MASK ((sizeof(void *))-1) |
63 | 63 |
64 /* | |
65 * Other than empty segments, these are the only ones that are allowed. | |
66 */ | |
67 struct NaClPhdrChecks nacl_phdr_check_data[] = { | |
68 /* phdr */ | |
69 { PT_PHDR, PF_R, PCA_IGNORE, 0, 0, }, | |
70 /* text */ | |
71 { PT_LOAD, PF_R|PF_X, PCA_TEXT_CHECK, 1, NACL_TRAMPOLINE_END, }, | |
72 /* rodata */ | |
73 { PT_LOAD, PF_R, PCA_NONE, 0, 0, }, | |
74 /* data/bss */ | |
75 { PT_LOAD, PF_R|PF_W, PCA_NONE, 0, 0, }, | |
76 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm | |
77 /* arm exception handling unwind info (for c++)*/ | |
78 /* TODO(robertm): for some reason this does NOT end up in ro maybe because | |
79 * it is relocatable. Try hacking the linker script to move it. | |
80 */ | |
81 { PT_ARM_EXIDX, PF_R, PCA_IGNORE, 0, 0, }, | |
82 #endif | |
83 /* | |
84 * allow optional GNU stack permission marker, but require that the | |
85 * stack is non-executable. | |
86 */ | |
87 { PT_GNU_STACK, PF_R|PF_W, PCA_NONE, 0, 0, }, | |
88 }; | |
89 | 64 |
90 | 65 NaClErrorCode NaClAppLoadFile(struct Gio *gp, |
91 NaClErrorCode NaClProcessPhdrs(struct NaClApp *nap) { | 66 struct NaClApp *nap, |
92 /* Scan phdrs and do sanity checks in-line. Verify that the load | 67 enum NaClAbiCheckOption check_abi) { |
93 * address is NACL_TRAMPOLINE_END, that we have a single text | 68 NaClErrorCode ret = LOAD_INTERNAL; |
94 * segment. Data and TLS segments are not required, though it is | 69 NaClErrorCode subret; |
95 * hard to avoid with standard tools, but in any case there should | 70 uintptr_t max_vaddr; |
96 * be at most one each. Ensure that no segment's vaddr is outside | 71 struct NaClElfImage *image = NULL; |
97 * of the address space. Ensure that PT_GNU_STACK is present, and | |
98 * that x is off. | |
99 */ | |
100 int seen_seg[NACL_ARRAY_SIZE(nacl_phdr_check_data)]; | |
101 | |
102 int segnum; | |
103 Elf32_Phdr *php; | |
104 size_t j; | |
105 uintptr_t max_vaddr; | |
106 | |
107 memset(seen_seg, 0, sizeof seen_seg); | |
108 max_vaddr = NACL_TRAMPOLINE_END; | |
109 /* | |
110 * nacl_phdr_check_data is small, so O(|check_data| * nap->elf_hdr.e_phum) | |
111 * is okay. | |
112 */ | |
113 for (segnum = 0; segnum < nap->elf_hdr.e_phnum; ++segnum) { | |
114 php = &nap->phdrs[segnum]; | |
115 NaClLog(3, "Looking at segment %d, type 0x%x, p_flags 0x%x\n", | |
116 segnum, php->p_type, php->p_flags); | |
117 php->p_flags &= ~PF_MASKOS; | |
118 for (j = 0; | |
119 j < NACL_ARRAY_SIZE(nacl_phdr_check_data); | |
120 ++j) { | |
121 if (php->p_type == nacl_phdr_check_data[j].p_type | |
122 && php->p_flags == nacl_phdr_check_data[j].p_flags) { | |
123 NaClLog(2, "Matched nacl_phdr_check_data[%"PRIdS"]\n", j); | |
124 if (seen_seg[j]) { | |
125 NaClLog(2, "Segment %d is a type that has been seen\n", segnum); | |
126 return LOAD_DUP_SEGMENT; | |
127 } | |
128 ++seen_seg[j]; | |
129 | |
130 if (PCA_IGNORE == nacl_phdr_check_data[j].action) { | |
131 NaClLog(3, "Ignoring\n"); | |
132 goto next_seg; | |
133 } | |
134 | |
135 if (0 != php->p_memsz) { | |
136 /* | |
137 * We will load this segment later. Do the sanity checks. | |
138 */ | |
139 if (0 != nacl_phdr_check_data[j].p_vaddr | |
140 && (nacl_phdr_check_data[j].p_vaddr != php->p_vaddr)) { | |
141 NaClLog(2, | |
142 ("Segment %d: bad virtual address: 0x%08x," | |
143 " expected 0x%08x\n"), | |
144 segnum, | |
145 php->p_vaddr, | |
146 nacl_phdr_check_data[j].p_vaddr); | |
147 return LOAD_SEGMENT_BAD_LOC; | |
148 } | |
149 if (php->p_vaddr < NACL_TRAMPOLINE_END) { | |
150 NaClLog(2, "Segment %d: virtual address (0x%08x) too low\n", | |
151 segnum, | |
152 php->p_vaddr); | |
153 return LOAD_SEGMENT_OUTSIDE_ADDRSPACE; | |
154 } | |
155 /* | |
156 * integer overflow? Elf32_Addr and Elf32_Word are uint32_t, | |
157 * so the addition/comparison is well defined. | |
158 */ | |
159 if (php->p_vaddr + php->p_memsz < php->p_vaddr) { | |
160 NaClLog(2, | |
161 "Segment %d: p_memsz caused integer overflow\n", | |
162 segnum); | |
163 return LOAD_SEGMENT_OUTSIDE_ADDRSPACE; | |
164 } | |
165 if (php->p_vaddr + php->p_memsz >= (1U << nap->addr_bits)) { | |
166 NaClLog(2, | |
167 "Segment %d: too large, ends at 0x%08x\n", | |
168 segnum, | |
169 php->p_vaddr + php->p_memsz); | |
170 return LOAD_SEGMENT_OUTSIDE_ADDRSPACE; | |
171 } | |
172 if (php->p_filesz > php->p_memsz) { | |
173 NaClLog(2, | |
174 ("Segment %d: file size 0x%08x larger" | |
175 " than memory size 0x%08x\n"), | |
176 segnum, | |
177 php->p_filesz, | |
178 php->p_memsz); | |
179 return LOAD_SEGMENT_BAD_PARAM; | |
180 } | |
181 | |
182 php->p_flags |= PF_OS_WILL_LOAD; | |
183 /* record our decision that we will load this segment */ | |
184 | |
185 /* | |
186 * NACL_TRAMPOLINE_END <= p_vaddr | |
187 * <= p_vaddr + p_memsz | |
188 * < (1U << nap->addr_bits) | |
189 */ | |
190 if (max_vaddr < php->p_vaddr + php->p_memsz) { | |
191 max_vaddr = php->p_vaddr + php->p_memsz; | |
192 } | |
193 } | |
194 | |
195 switch (nacl_phdr_check_data[j].action) { | |
196 case PCA_NONE: | |
197 break; | |
198 case PCA_TEXT_CHECK: | |
199 if (0 == php->p_memsz) { | |
200 return LOAD_BAD_ELF_TEXT; | |
201 } | |
202 nap->text_region_bytes = php->p_filesz; | |
203 break; | |
204 case PCA_IGNORE: | |
205 break; | |
206 } | |
207 goto next_seg; | |
208 } | |
209 } | |
210 /* segment not in nacl_phdr_check_data */ | |
211 if (0 == php->p_memsz) { | |
212 NaClLog(3, "Segment %d zero size: ignored\n", segnum); | |
213 continue; | |
214 } | |
215 NaClLog(2, | |
216 "Segment %d is of unexpected type 0x%x, flag 0x%x\n", | |
217 segnum, | |
218 php->p_type, | |
219 php->p_flags); | |
220 return LOAD_BAD_SEGMENT; | |
221 next_seg: | |
222 ; | |
223 } | |
224 for (j = 0; | |
225 j < NACL_ARRAY_SIZE(nacl_phdr_check_data); | |
226 ++j) { | |
227 if (nacl_phdr_check_data[j].required && !seen_seg[j]) { | |
228 return LOAD_REQUIRED_SEG_MISSING; | |
229 } | |
230 } | |
231 nap->data_end = nap->break_addr = max_vaddr; | |
232 /* | |
233 * Memory allocation will use NaClRoundPage(nap->break_addr), but | |
234 * the system notion of break is always an exact address. Even | |
235 * though we must allocate and make accessible multiples of pages, | |
236 * the linux-style brk system call (which returns current break on | |
237 * failure) permits an arbitrarily aligned address as argument. | |
238 */ | |
239 | |
240 return LOAD_OK; | |
241 } | |
242 | |
243 | |
244 static void NaClDumpElfHeader(Elf32_Ehdr *elf_hdr) { | |
245 #define DUMP(m,f) do { NaClLog(2, \ | |
246 #m " = %" f "\n", \ | |
247 elf_hdr->m); } while (0) | |
248 DUMP(e_ident+1, ".3s"); | |
249 DUMP(e_type, "#x"); | |
250 DUMP(e_machine, "#x"); | |
251 DUMP(e_version, "#x"); | |
252 DUMP(e_entry, "#x"); | |
253 DUMP(e_phoff, "#x"); | |
254 DUMP(e_shoff, "#x"); | |
255 DUMP(e_flags, "#x"); | |
256 DUMP(e_ehsize, "#x"); | |
257 DUMP(e_phentsize, "#x"); | |
258 DUMP(e_phnum, "#x"); | |
259 DUMP(e_shentsize, "#x"); | |
260 DUMP(e_shnum, "#x"); | |
261 DUMP(e_shstrndx, "#x"); | |
262 #undef DUMP | |
263 NaClLog(2, "sizeof(Elf32_Ehdr) = %x\n", (int) sizeof *elf_hdr); | |
264 } | |
265 | |
266 | |
267 static NaClErrorCode NaClValidateElfHeader(Elf32_Ehdr *hdr, | |
268 enum NaClAbiMismatchOption | |
269 abi_mismatch_option) { | |
270 if (memcmp(hdr->e_ident, ELFMAG, SELFMAG)) { | |
271 return LOAD_BAD_ELF_MAGIC; | |
272 } | |
273 if (ELFCLASS32 != hdr->e_ident[EI_CLASS]) { | |
274 return LOAD_NOT_32_BIT; | |
275 } | |
276 | |
277 #if !defined(DANGEROUS_DEBUG_MODE_DISABLE_INNER_SANDBOX) | |
278 if (ELFOSABI_NACL != hdr->e_ident[EI_OSABI]) { | |
279 NaClLog(LOG_ERROR, "Expected OSABI %d, got %d\n", | |
280 ELFOSABI_NACL, | |
281 hdr->e_ident[EI_OSABI]); | |
282 if (abi_mismatch_option == NACL_ABI_MISMATCH_OPTION_ABORT) { | |
283 return LOAD_BAD_ABI; | |
284 } | |
285 } | |
286 | |
287 if (EF_NACL_ABIVERSION != hdr->e_ident[EI_ABIVERSION]) { | |
288 NaClLog(LOG_ERROR, "Expected ABIVERSION %d, got %d\n", | |
289 EF_NACL_ABIVERSION, | |
290 hdr->e_ident[EI_ABIVERSION]); | |
291 if (abi_mismatch_option == NACL_ABI_MISMATCH_OPTION_ABORT) { | |
292 return LOAD_BAD_ABI; | |
293 } | |
294 } | |
295 #else | |
296 UNREFERENCED_PARAMETER(abi_mismatch_option); | |
297 #endif | |
298 | |
299 if (ET_EXEC != hdr->e_type) { | |
300 return LOAD_NOT_EXEC; | |
301 } | |
302 | |
303 if (EM_EXPECTED_BY_NACL != hdr->e_machine) { | |
304 return LOAD_BAD_MACHINE; | |
305 } | |
306 | |
307 if (EV_CURRENT != hdr->e_version) { | |
308 return LOAD_BAD_ELF_VERS; | |
309 } | |
310 | |
311 return LOAD_OK; | |
312 } | |
313 | |
314 | |
315 static void NaClDumpElfProgramHeader(Elf32_Phdr *phdr) { | |
316 #define DUMP(mem) do { \ | |
317 NaClLog(2, "%s: %x\n", #mem, phdr->mem); \ | |
318 } while (0) | |
319 | |
320 DUMP(p_type); | |
321 DUMP(p_offset); | |
322 DUMP(p_vaddr); | |
323 DUMP(p_paddr); | |
324 DUMP(p_filesz); | |
325 DUMP(p_memsz); | |
326 DUMP(p_flags); | |
327 NaClLog(2, " (%s %s %s)\n", | |
328 (phdr->p_flags & PF_R) ? "PF_R" : "", | |
329 (phdr->p_flags & PF_W) ? "PF_W" : "", | |
330 (phdr->p_flags & PF_X) ? "PF_X" : ""); | |
331 DUMP(p_align); | |
332 #undef DUMP | |
333 NaClLog(2, "\n"); | |
334 } | |
335 | |
336 | |
337 NaClErrorCode NaClAppLoadFile(struct Gio *gp, | |
338 struct NaClApp *nap, | |
339 enum NaClAbiMismatchOption abi_mismatch_option) { | |
340 NaClErrorCode ret = LOAD_INTERNAL; | |
341 NaClErrorCode subret; | |
342 int cur_ph; | |
343 | |
344 /* NACL_MAX_ADDR_BITS < 32 */ | 72 /* NACL_MAX_ADDR_BITS < 32 */ |
345 if (nap->addr_bits > NACL_MAX_ADDR_BITS) { | 73 if (nap->addr_bits > NACL_MAX_ADDR_BITS) { |
346 ret = LOAD_ADDR_SPACE_TOO_BIG; | 74 ret = LOAD_ADDR_SPACE_TOO_BIG; |
347 goto done; | 75 goto done; |
348 } | 76 } |
349 | 77 |
350 nap->stack_size = NaClRoundAllocPage(nap->stack_size); | 78 nap->stack_size = NaClRoundAllocPage(nap->stack_size); |
351 | 79 |
352 /* nap->addr_bits <= NACL_MAX_ADDR_BITS < 32 */ | 80 /* temporay object will be deleted at end of function */ |
353 if ((*gp->vtbl->Read)(gp, | 81 image = NaClElfImageNew(gp); |
354 &nap->elf_hdr, | 82 #if !defined(DANGEROUS_DEBUG_MODE_DISABLE_INNER_SANDBOX) |
355 sizeof nap->elf_hdr) | 83 check_abi = NACL_ABI_CHECK_OPTION_CHECK; |
356 != sizeof nap->elf_hdr) { | 84 #endif |
357 ret = LOAD_READ_ERROR; | 85 |
358 goto done; | 86 if (check_abi == NACL_ABI_CHECK_OPTION_CHECK) { |
| 87 subret = NaClElfImageValidateAbi(image); |
| 88 if (subret != LOAD_OK) { |
| 89 ret = subret; |
| 90 goto done; |
| 91 } |
| 92 |
359 } | 93 } |
360 | 94 |
361 NaClDumpElfHeader(&nap->elf_hdr); | 95 subret = NaClElfImageValidateElfHeader(image); |
362 | |
363 subret = NaClValidateElfHeader(&nap->elf_hdr, abi_mismatch_option); | |
364 if (subret != LOAD_OK) { | 96 if (subret != LOAD_OK) { |
365 ret = subret; | 97 ret = subret; |
366 goto done; | 98 goto done; |
367 } | 99 } |
368 | 100 |
369 nap->entry_pt = nap->elf_hdr.e_entry; | 101 subret = NaClElfImageValidateProgramHeaders(image, |
370 | 102 nap->addr_bits, |
371 if (nap->elf_hdr.e_flags & EF_NACL_ALIGN_MASK) { | 103 &nap->text_region_bytes, |
372 unsigned long eflags = nap->elf_hdr.e_flags & EF_NACL_ALIGN_MASK; | 104 &max_vaddr); |
373 if (eflags == EF_NACL_ALIGN_16) { | |
374 nap->align_boundary = 16; | |
375 } else if (eflags == EF_NACL_ALIGN_32) { | |
376 nap->align_boundary = 32; | |
377 } else { | |
378 ret = LOAD_BAD_ABI; | |
379 goto done; | |
380 } | |
381 } else { | |
382 nap->align_boundary = 32; | |
383 } | |
384 | |
385 /* read program headers */ | |
386 if (nap->elf_hdr.e_phnum > NACL_MAX_PROGRAM_HEADERS) { | |
387 ret = LOAD_TOO_MANY_SECT; /* overloaded */ | |
388 goto done; | |
389 } | |
390 | |
391 /* TODO(robertm): determine who allocated this */ | |
392 free(nap->phdrs); | |
393 | |
394 nap->phdrs = malloc(nap->elf_hdr.e_phnum * sizeof nap->phdrs[0]); | |
395 if (!nap->phdrs) { | |
396 ret = LOAD_NO_MEMORY; | |
397 goto done; | |
398 } | |
399 if (nap->elf_hdr.e_phentsize < sizeof nap->phdrs[0]) { | |
400 ret = LOAD_BAD_SECT; | |
401 goto done; | |
402 } | |
403 for (cur_ph = 0; cur_ph < nap->elf_hdr.e_phnum; ++cur_ph) { | |
404 if ((*gp->vtbl->Seek)(gp, | |
405 nap->elf_hdr.e_phoff | |
406 + cur_ph * nap->elf_hdr.e_phentsize, | |
407 SEEK_SET) == -1) { | |
408 ret = LOAD_BAD_SECT; | |
409 goto done; | |
410 } | |
411 if ((*gp->vtbl->Read)(gp, | |
412 &nap->phdrs[cur_ph], | |
413 sizeof nap->phdrs[0]) | |
414 != sizeof nap->phdrs[0]) { | |
415 ret = LOAD_BAD_SECT; | |
416 goto done; | |
417 } | |
418 | |
419 | |
420 NaClDumpElfProgramHeader(&nap->phdrs[cur_ph]); | |
421 } | |
422 | |
423 /* | |
424 * We need to determine the size of the CS region. (The DS and SS | |
425 * region sizes are obvious -- the entire application address | |
426 * space.) NaClProcessPhdrs will figure out nap->text_region_bytes. | |
427 */ | |
428 | |
429 subret = NaClProcessPhdrs(nap); | |
430 if (subret != LOAD_OK) { | 105 if (subret != LOAD_OK) { |
431 ret = subret; | 106 ret = subret; |
432 goto done; | 107 goto done; |
433 } | 108 } |
434 | 109 |
| 110 nap->break_addr = max_vaddr; |
| 111 nap->data_end = max_vaddr; |
| 112 |
| 113 nap->align_boundary = NaClElfImageGetAlignBoundary(image); |
| 114 if (nap->align_boundary == 0) { |
| 115 ret = LOAD_BAD_ABI; |
| 116 goto done; |
| 117 } |
| 118 |
| 119 nap->entry_pt = NaClElfImageGetEntryPoint(image); |
| 120 |
| 121 NaClLog(2, |
| 122 "text_region_bytes: %08x " |
| 123 "break_add: %08"PRIxPTR" " |
| 124 "data_end: %08"PRIxPTR" " |
| 125 "entry_pt: %08x " |
| 126 "align_boundary: %08x\n", |
| 127 nap->text_region_bytes, |
| 128 nap->break_addr, |
| 129 nap->data_end, |
| 130 nap->entry_pt, |
| 131 nap->align_boundary); |
435 if (!NaClAddrIsValidEntryPt(nap, nap->entry_pt)) { | 132 if (!NaClAddrIsValidEntryPt(nap, nap->entry_pt)) { |
436 ret = LOAD_BAD_ENTRY; | 133 ret = LOAD_BAD_ENTRY; |
437 goto done; | 134 goto done; |
438 } | 135 } |
439 | 136 |
440 NaClLog(2, "Allocating address space\n"); | 137 NaClLog(2, "Allocating address space\n"); |
441 subret = NaClAllocAddrSpace(nap); | 138 subret = NaClAllocAddrSpace(nap); |
442 if (subret != LOAD_OK) { | 139 if (subret != LOAD_OK) { |
443 ret = subret; | 140 ret = subret; |
444 goto done; | 141 goto done; |
445 } | 142 } |
446 | 143 |
447 NaClLog(2, "Loading into memory\n"); | 144 NaClLog(2, "Loading into memory\n"); |
448 subret = NaClLoadImage(gp, nap); | 145 subret = NaClElfImageLoad(image, gp, nap->addr_bits, nap->mem_start); |
449 if (subret != LOAD_OK) { | 146 if (subret != LOAD_OK) { |
450 ret = subret; | 147 ret = subret; |
451 goto done; | 148 goto done; |
452 } | 149 } |
453 | 150 |
| 151 NaClFillEndOfTextRegion(nap); |
| 152 |
454 #if !defined(DANGEROUS_DEBUG_MODE_DISABLE_INNER_SANDBOX) | 153 #if !defined(DANGEROUS_DEBUG_MODE_DISABLE_INNER_SANDBOX) |
455 NaClLog(2, "Validating image\n"); | 154 NaClLog(2, "Validating image\n"); |
456 subret = NaClValidateImage(nap); | 155 subret = NaClValidateImage(nap); |
457 if (subret != LOAD_OK) { | 156 if (subret != LOAD_OK) { |
458 ret = subret; | 157 ret = subret; |
459 goto done; | 158 goto done; |
460 } | 159 } |
461 #endif | 160 #endif |
462 | 161 |
463 NaClLog(2, "Installing trampoline\n"); | 162 NaClLog(2, "Installing trampoline\n"); |
(...skipping 16 matching lines...) Expand all Loading... |
480 NaClLog(2, "Applying memory protection\n"); | 179 NaClLog(2, "Applying memory protection\n"); |
481 | 180 |
482 subret = NaClMemoryProtection(nap); | 181 subret = NaClMemoryProtection(nap); |
483 if (subret != LOAD_OK) { | 182 if (subret != LOAD_OK) { |
484 ret = subret; | 183 ret = subret; |
485 goto done; | 184 goto done; |
486 } | 185 } |
487 | 186 |
488 ret = LOAD_OK; | 187 ret = LOAD_OK; |
489 done: | 188 done: |
| 189 NaClElfImageDelete(image); |
490 return ret; | 190 return ret; |
491 } | 191 } |
492 | 192 |
493 int NaClAddrIsValidEntryPt(struct NaClApp *nap, | 193 int NaClAddrIsValidEntryPt(struct NaClApp *nap, |
494 uintptr_t addr) { | 194 uintptr_t addr) { |
495 if (0 != (addr & (nap->align_boundary - 1))) { | 195 if (0 != (addr & (nap->align_boundary - 1))) { |
496 return 0; | 196 return 0; |
497 } | 197 } |
498 | 198 |
499 return addr < NACL_TRAMPOLINE_END + nap->text_region_bytes; | 199 return addr < NACL_TRAMPOLINE_END + nap->text_region_bytes; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 if (!natp) { | 308 if (!natp) { |
609 goto cleanup; | 309 goto cleanup; |
610 } | 310 } |
611 | 311 |
612 nap->running = 1; | 312 nap->running = 1; |
613 | 313 |
614 /* e_entry is user addr */ | 314 /* e_entry is user addr */ |
615 if (!NaClAppThreadAllocSegCtor(natp, | 315 if (!NaClAppThreadAllocSegCtor(natp, |
616 nap, | 316 nap, |
617 1, | 317 1, |
618 nap->elf_hdr.e_entry, | 318 nap->entry_pt, |
619 NaClSysToUser(nap, stack_ptr), | 319 NaClSysToUser(nap, stack_ptr), |
620 NaClUserToSys(nap, nap->break_addr), | 320 NaClUserToSys(nap, nap->break_addr), |
621 1)) { | 321 1)) { |
622 retval = 0; | 322 retval = 0; |
623 goto cleanup; | 323 goto cleanup; |
624 } | 324 } |
625 | 325 |
626 /* | 326 /* |
627 * NB: Hereafter locking is required to access nap. | 327 * NB: Hereafter locking is required to access nap. |
628 */ | 328 */ |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 nap, | 376 nap, |
677 0, | 377 0, |
678 prog_ctr, | 378 prog_ctr, |
679 stack_ptr, | 379 stack_ptr, |
680 sys_tdb, | 380 sys_tdb, |
681 tdb_size)) { | 381 tdb_size)) { |
682 return -NACL_ABI_ENOMEM; | 382 return -NACL_ABI_ENOMEM; |
683 } | 383 } |
684 return 0; | 384 return 0; |
685 } | 385 } |
OLD | NEW |