Fix: $(HAMMER) -> scons
[nativeclient.git] / service_runtime / sel_ldr.h
blob54193636d977aba36dec94f7b1b3f095b4310d72
1 /*
2 * Copyright 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * NaCl Simple/secure ELF loader (NaCl SEL).
35 * This loader can only process NaCl object files as produced using
36 * the NaCl toolchain. Other ELF files will be rejected.
38 * The primary function, NaClAppLoadFile, parses an ELF file,
39 * allocates memory, loads the relocatable image from the ELF file
40 * into memory, and performs relocation. NaClAppRun runs the
41 * resultant program.
43 * This loader is written in C so that it can be used by C-only as
44 * well as C++ applications. Other languages should also be able to
45 * use their foreign-function interfaces to invoke C code.
47 * This loader must be part of the NaCl TCB, since it directly handles
48 * externally supplied input (the ELF file). Any security
49 * vulnerabilities in handling the ELF image, e.g., buffer or integer
50 * overflows, can put the application at risk.
53 #ifndef SERVICE_RUNTIME_SEL_LDR_H__
54 #define SERVICE_RUNTIME_SEL_LDR_H__ 1
56 #include "native_client/include/nacl_platform.h"
57 #include "native_client/include/portability.h"
58 #include "native_client/include/nacl_base.h"
60 #include "native_client/service_runtime/dyn_array.h"
61 #include "native_client/service_runtime/gio.h"
62 #include "native_client/service_runtime/nacl_config.h"
63 #include "native_client/service_runtime/nacl_log.h"
64 #include "native_client/service_runtime/nacl_sync.h"
65 #include "native_client/service_runtime/nacl_sync_queue.h"
66 #include "native_client/service_runtime/nacl_desc_base.h"
67 #include "native_client/service_runtime/sel_mem.h"
68 #include "native_client/service_runtime/sel_util.h"
70 #include "native_client/service_runtime/nacl_error_code.h"
72 #include "native_client/include/portability.h"
74 #include "native_client/intermodule_comm/nacl_imc_c.h"
76 EXTERN_C_BEGIN
78 #define NACL_SERVICE_PORT_DESCRIPTOR 3
79 #define NACL_SERVICE_ADDRESS_DESCRIPTOR 4
81 extern int using_debug_configuration;
83 #define NACL_SELF_CHECK 1
85 #define NACL_MAX_ADDR_BITS (8 + 20)
86 /* wp: NACL_MAX_ADDR_BITS < 32, see NaClAppLoadFile */
87 #define NACL_DEFAULT_ENTRY_PT "NaClMain"
90 * the extra space for the trampoline syscall code and the thread
91 * contexts must be a multiple of the page size.
93 * TODO: leave an inaccessible page at page 0 to catch null
94 * pointers, so the first syscall will then be at page 1.
96 * TODO: change to trampoline shift of 16 (64K)
98 #define NACL_TRAMPOLINE_SHIFT 16
99 #define NACL_TRAMPOLINE_SIZE (1 << NACL_TRAMPOLINE_SHIFT)
100 #define NACL_THREAD_CTX_SIZE (64 << 10)
102 #define NACL_DEFAULT_ALLOC_MAX (32 << 20) /* total brk and mmap allocs */
103 #define NACL_DEFAULT_STACK_MAX (16 << 20) /* main thread stack */
105 #define NACL_NOOP_OPCODE 0x90
106 #define NACL_HALT_OPCODE 0xf4
108 #define NACL_DATA_SANDBOXING 0
110 * If 0, address space is allocated to permit text sandboxing or
111 * control flow integrity enforcement via masking. LDT is used to
112 * enforce data access restrictions.
114 * If 1, address space is allocated to permit both text and data
115 * sandboxing. Code for this is not as yet written/tested and should
116 * be needed only for 64-bit x86 windows.
120 * Finds the lowest 1 bit in PF_MASKOS. Assumes that at least one
121 * bit is set, and that this bit is not the highest-order bit.
123 * Let us denote PF_MASKOS by n. Assume n \ne 2^{31}. Let the k^{th}
124 * bit be the lowest order bit that is set, i.e.,
125 * n = m \cdot 2^{k+1} + 2^k, with k,m integers, m \ge 0, and 0 \le k < 31.
126 * then (here lhs is C notation, rhs is LaTeX notation):
127 * n ^ (n-1) = (m \cdot 2^{k+1} + 2^k)
128 * \oplus (m \dot 2^{k+1} + 2^{k-1} + \ldots + 1)
129 * = 2^k + 2^{k-1} + \ldots + 1
130 * = (2^{k+1}-1)
131 * so
132 * ((n ^ (n-1)) + 1U) = 2^{k+1}, (since k < 31, no overflow occurs) and
133 * ((n ^ (n-1)) + 1U) >> 1 = 2^k. QED.
135 #define PF_OS_WILL_LOAD (((PF_MASKOS ^ (PF_MASKOS-1)) + 1U) >> 1)
136 #if PF_MASKOS == (1 << 31)
137 # error "PF_MASKOS too large, invariant needed for PF_OS_WILL_LOAD violated"
138 #endif
140 #if NACL_WINDOWS
141 #define WINDOWS_EXCEPTION_TRY do { __try {
142 #define WINDOWS_EXCEPTION_CATCH } __except(EXCEPTION_EXECUTE_HANDLER) { \
143 NaClLog(LOG_ERROR, \
144 "Unhandled Windows exception\n"); \
145 exit(1); \
147 } while(0)
148 #else
149 #define WINDOWS_EXCEPTION_TRY do {
150 #define WINDOWS_EXCEPTION_CATCH } while(0)
151 #endif
153 struct NaClAppThread;
155 struct NaClApp {
157 * public, user settable.
159 uint32_t addr_bits;
160 uint32_t max_data_alloc, stack_size;
162 * max_data_alloc controls how much total data memory can be
163 * allocated to the NaCl process; this is initialized data,
164 * uninitialized data, and heap and affects the brk system call.
165 * the text size and rodata size are not included, even though in
166 * NaCl the text and rodata pages are also backed by the pager
167 * since due to relocation the text pages and rodata contents
168 * cannot simply be memory mapped from the executable.
170 * stack_size is the maximum size of the (main) stack. The stack
171 * memory is eager allocated (mapped in w/o MAP_NORESERVE) so
172 * there must be enough swap space; page table entries are not
173 * populated (no MAP_POPULATE), so actual accesses will likely
174 * incur page faults.
177 /* determined at load time; OS-determined */
178 /* read-only */
179 uintptr_t mem_start;
180 uintptr_t xlate_base;
182 /* only used for ET_EXEC: for CS restriction */
183 uint32_t text_region_bytes; /* ro. memsz */
185 uintptr_t tls_start; /* vaddr */
186 uint32_t tls_size; /* memsz */
187 uintptr_t data_end;
188 /* see break_addr below */
190 Elf32_Addr entry_pt;
193 * Alignment boundary for validation (16 or 32).
195 int align_boundary;
197 /* private */
198 Elf32_Ehdr elf_hdr;
201 * phdrs and sections are mutually exclusive.
203 * phdrs non-NULL means that an ELF executable -- with starting text
204 * address of NACL_TRAMPOLINE_SIZE -- is used. sections headers are
205 * still loaded, for things like bss size. ???? TODO
207 * when phdrs is NULL, a relocatable object was used and sections
208 * will be non-NULL, with the loader performing relocation as part
209 * of the image load. This is insufficient for C++ since preinit
210 * and init code is not executed, so global constructors aren't run,
211 * and multiple section groups for template instantiation are not
212 * handled properly, among other issues.
214 Elf32_Phdr *phdrs; /* elf_hdr.e_phnum entries */
216 /* common to both ELF executables and relocatable load images */
218 uintptr_t springboard_addr; /* relative to mem_start */
220 * springboard code addr for context switching into app sandbox, relative
221 * to code sandbox CS
225 * The socket at which the app should be accepting connections. The
226 * corresponding socket address are made available by the JavaScript
227 * bridge to other NaCl modules.
229 struct NaClDesc *service_port;
230 struct NaClDesc *service_address;
232 struct NaClMutex mu;
233 struct NaClCondVar cv;
235 * runtime info below, thread state, etc; initialized only when app
236 * is run. Mutex mu protects access to mem_map and other member
237 * variables while the application is running and may be
238 * multithreaded; thread, desc members have their own locks. At
239 * other times it is assumed that only one thread is
240 * constructing/loading the NaClApp and that no mutual exclusion is
241 * needed.
245 * memory map is in user addresses.
247 struct NaClVmmap mem_map;
249 int running;
250 int exit_status;
253 * enforce that some "special" syscalls may only be made from the
254 * main/privileged thread
256 int restrict_to_main_thread;
257 /* all threads enqueue the "special" syscalls to the work queue */
258 struct NaClSyncQueue work_queue;
260 uint16_t code_seg_sel;
261 uint16_t data_seg_sel;
263 uintptr_t break_addr; /* user addr */
264 /* data_end <= break_addr is an invariant */
266 int freeze_thread_ops;
267 /* used when process is killed, or when address space move is needed */
270 * Thread table lock threads_mu is higher in the locking order than
271 * the thread locks, i.e., threads_mu must be acqured w/o holding
272 * any per-thread lock (natp->mu).
274 struct NaClMutex threads_mu;
275 struct NaClCondVar threads_cv;
276 struct DynArray threads; /* NaClAppThread pointers */
277 int num_threads; /* number actually running */
279 struct NaClMutex desc_mu;
280 struct DynArray desc_tbl; /* NaClDesc pointers */
283 #define NACL_MAX_PROGRAM_HEADERS 128
285 enum NaClPhdrCheckAction {
286 PCA_NONE,
287 PCA_TEXT_CHECK,
288 PCA_SAVE_TLS_INFO,
289 PCA_IGNORE, /* ignore this segment. currently used only for PT_PHDR. */
292 struct NaClPhdrChecks {
293 Elf32_Word p_type;
294 Elf32_Word p_flags; /* rwx */
295 enum NaClPhdrCheckAction action;
296 int required; /* only for text for now */
297 Elf32_Word p_vaddr; /* if non-zero, vaddr must be this */
301 void NaClAppIncrVerbosity(void);
303 int NaClAppCtor(struct NaClApp *nap);
305 void NaClAppDtor(struct NaClApp *nap);
307 void NaClAppFreeAllMemory(struct NaClApp *nap);
310 * Loads a NaCl ELF file into memory in preparation for running it.
312 * gp is a pointer to a generic I/O object and should be a GioMem with
313 * a memory buffer containing the file read entirely into memory if
314 * the file system might be subject to race conditions (e.g., another
315 * thread / process might modify a downloaded NaCl ELF file while we
316 * are loading it here).
318 * nap is a pointer to the NaCl object that is being filled in. it
319 * should be properly constructed via NaClAppCtor.
321 * return value: one of the LOAD_* values below. TODO: add some error
322 * detail string and hang that off the nap object, so that more
323 * details are available w/o incrementing verbosity (and polluting
324 * stdout).
326 * note: it may be necessary to flush the icache if the memory
327 * allocated for use had already made it into the icache from another
328 * NaCl application instance, and the icache does not detect
329 * self-modifying code / data writes and automatically invalidate the
330 * cache lines.
332 NaClErrorCode NaClAppLoadFile(struct Gio *gp,
333 struct NaClApp *nap);
335 size_t NaClAlignPad(size_t val,
336 size_t align);
338 void NaClAppPrintDetails(struct NaClApp *nap,
339 struct Gio *gp);
341 uint32_t NaClLoad32(uintptr_t addr);
343 void NaClStore32(uintptr_t addr,
344 uint32_t v);
346 NaClErrorCode NaClLoadImage(struct Gio *gp,
347 struct NaClApp *nap);
349 void NaClIgnoreValidatorResult();
350 NaClErrorCode NaClValidateImage(struct NaClApp *nap);
353 int NaClAddrIsValidEntryPt(struct NaClApp *nap,
354 uintptr_t addr);
357 * Takes ownership of descriptor, i.e., when NaCl app closes, it's gone.
359 void NaClAddHostDescriptor(struct NaClApp *nap,
360 int host_os_desc,
361 int mode,
362 int nacl_desc);
365 * Takes ownership of handle.
367 void NaClAddImcHandle(struct NaClApp *nap,
368 NaClHandle h,
369 int nacl_desc);
371 void NaClAddImcAddr(struct NaClApp *nap,
372 struct NaClSocketAddress const *addr,
373 int nacl_desc);
376 * Used to launch the main thread. NB: calling thread may in the
377 * future become the main NaCl app thread, and this function will
378 * return only after the NaCl app main thread exits. In such an
379 * alternative design, NaClWaitForMainThreadToExit will become a
380 * no-op.
382 int NaClCreateMainThread(struct NaClApp *nap,
383 int argc,
384 char **argv,
385 char **envp);
387 int NaClWaitForMainThreadToExit(struct NaClApp *nap);
390 * Used by syscall code.
392 int32_t NaClCreateAdditionalThread(struct NaClApp *nap,
393 uintptr_t eip,
394 uintptr_t esp,
395 uintptr_t sys_tdb,
396 size_t tdb_size);
398 void NaClLoadTrampoline(struct NaClApp *nap);
400 void NaClLoadSpringboard(struct NaClApp *nap);
402 static const uintptr_t kNaClBadAddress = (uintptr_t) -1;
405 * Routines to translate addresses between user and "system" or
406 * service runtime addresses. the *Addr* versions will return
407 * kNaClBadAddress if the usr address is outside of the user address
408 * space, e.g., if the input addresses for *UserToSys* is outside of
409 * (1<<nap->addr_bits), and correspondingly for *SysToUser* if the
410 * input system address does not correspond to a user address.
411 * Generally, the *Addr* versions are used when the addresses come
412 * from untrusted usre code, and kNaClBadAddress would translate to an
413 * EINVAL return from a syscall. The *Range code ensures that the
414 * entire address range is in the user address space.
416 * Note that just because an address is within the address space, it
417 * doesn't mean that it is safe to acceess the memory: the page may be
418 * protected against access.
420 * The non-*Addr* versions abort the program rather than return an
421 * error indication.
425 * address translation routines. after a NaClApp is started, the
426 * member variables accessed by these routines are read-only, so no
427 * locking is needed to use these functions, as long as the NaClApp
428 * structure doesn't get destructed/deallocated.
430 * the first is used internally when a NULL pointer is okay, typically
431 * for address manipulation.
433 * the next two are for syscalls to do address translation, e.g., for
434 * system calls; -1 indicates an error, so the syscall can return
435 * EINVAL or EFAULT or whatever is appropriate.
437 * the latter two interfaces are for use everywhere else in the loader
438 * / service runtime and will log a fatal error and abort the process
439 * when an error is detected. (0 is not a good error indicator, since
440 * 0 is a valid user address.)
443 static INLINE uintptr_t NaClUserToSysAddrNullOkay(struct NaClApp *nap,
444 uintptr_t uaddr)
446 if (uaddr >= (1U << nap->addr_bits)) {
447 return kNaClBadAddress;
449 return uaddr + nap->xlate_base;
452 static INLINE uintptr_t NaClUserToSysAddr(struct NaClApp *nap,
453 uintptr_t uaddr)
455 if (0 == uaddr || uaddr >= (1U << nap->addr_bits)) {
456 return kNaClBadAddress;
458 return uaddr + nap->xlate_base;
461 static INLINE uintptr_t NaClSysToUserAddr(struct NaClApp *nap,
462 uintptr_t sysaddr)
464 if (sysaddr < nap->mem_start ||
465 sysaddr >= nap->mem_start + (1U << nap->addr_bits)) {
466 return kNaClBadAddress;
468 return sysaddr - nap->xlate_base;
471 static INLINE uintptr_t NaClUserToSysAddrRange(struct NaClApp *nap,
472 uintptr_t uaddr,
473 size_t count)
475 uintptr_t end_addr;
477 if (0 == uaddr) {
478 return kNaClBadAddress;
480 end_addr = uaddr + count;
481 if (end_addr < uaddr) {
482 /* unsigned wraparound */
483 return kNaClBadAddress;
485 if (end_addr >= (1U << nap->addr_bits)) {
486 return kNaClBadAddress;
488 return uaddr + nap->xlate_base;
491 static INLINE uintptr_t NaClUserToSys(struct NaClApp *nap,
492 uintptr_t uaddr)
494 if (0 == uaddr || uaddr >= (1U << nap->addr_bits)) {
495 NaClLog(LOG_FATAL,
496 "NaClUserToSys: uaddr 0x%08x, addr space %u bits",
497 uaddr, nap->addr_bits);
499 return uaddr + nap->xlate_base;
502 static INLINE uintptr_t NaClSysToUser(struct NaClApp *nap,
503 uintptr_t sysaddr)
505 if (sysaddr < nap->mem_start ||
506 sysaddr >= nap->mem_start + (1U << nap->addr_bits)) {
507 NaClLog(LOG_FATAL,
508 "NaclSysToUser: sysaddr 0x%08x, mem_start 0x%08x,"
509 " addr space %d bits",
510 sysaddr, nap->mem_start, nap->addr_bits);
512 return sysaddr - nap->xlate_base;
516 * Looks up a descriptor in the open-file table. An additional
517 * reference is taken on the returned NaClDesc object (if non-NULL).
518 * The caller is responsible for invoking NaClDescUnref() on it when
519 * done.
521 struct NaClDesc *NaClGetDesc(struct NaClApp *nap,
522 int d);
525 * Takes ownership of ndp.
527 void NaClSetDesc(struct NaClApp *nap,
528 int d,
529 struct NaClDesc *ndp);
532 int NaClSetAvail(struct NaClApp *nap,
533 struct NaClDesc *ndp);
536 * Versions that are called while already holding the desc_mu lock
538 struct NaClDesc *NaClGetDescMu(struct NaClApp *nap,
539 int d);
541 void NaClSetDescMu(struct NaClApp *nap,
542 int d,
543 struct NaClDesc *ndp);
545 int NaClSetAvailMu(struct NaClApp *nap,
546 struct NaClDesc *ndp);
549 int NaClAddThread(struct NaClApp *nap,
550 struct NaClAppThread *natp);
552 int NaClAddThreadMu(struct NaClApp *nap,
553 struct NaClAppThread *natp);
555 void NaClRemoveThread(struct NaClApp *nap,
556 int thread_num);
558 void NaClRemoveThreadMu(struct NaClApp *nap,
559 int thread_num);
561 struct NaClAppThread *NaClGetThreadMu(struct NaClApp *nap,
562 int thread_num);
564 void NaClAppVmmapUpdate(struct NaClApp *nap,
565 uintptr_t page_num,
566 size_t npages,
567 int prot,
568 struct NaClMemObj *nmop,
569 int remove);
571 uintptr_t NaClAppVmmapFindSpace(struct NaClApp *nap,
572 int num_pages);
574 uintptr_t NaClAppVmmapFindMapSpace(struct NaClApp *nap,
575 int num_pages);
577 void NaClCreateServiceSocket(struct NaClApp *nap);
579 void NaClSendServiceAddressTo(struct NaClApp *nap,
580 int desc);
582 void NaClDumpServiceAddressTo(struct NaClApp *nap,
583 int desc);
585 EXTERN_C_END
587 #endif