2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
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
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
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"
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
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"
141 #define WINDOWS_EXCEPTION_TRY do { __try {
142 #define WINDOWS_EXCEPTION_CATCH } __except(EXCEPTION_EXECUTE_HANDLER) { \
144 "Unhandled Windows exception\n"); \
149 #define WINDOWS_EXCEPTION_TRY do {
150 #define WINDOWS_EXCEPTION_CATCH } while(0)
153 struct NaClAppThread
;
157 * public, user settable.
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
177 /* determined at load time; OS-determined */
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 */
188 /* see break_addr below */
193 * Alignment boundary for validation (16 or 32).
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
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
;
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
245 * memory map is in user addresses.
247 struct NaClVmmap mem_map
;
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
{
289 PCA_IGNORE
, /* ignore this segment. currently used only for PT_PHDR. */
292 struct NaClPhdrChecks
{
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
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
332 NaClErrorCode
NaClAppLoadFile(struct Gio
*gp
,
333 struct NaClApp
*nap
);
335 size_t NaClAlignPad(size_t val
,
338 void NaClAppPrintDetails(struct NaClApp
*nap
,
341 uint32_t NaClLoad32(uintptr_t addr
);
343 void NaClStore32(uintptr_t addr
,
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
,
357 * Takes ownership of descriptor, i.e., when NaCl app closes, it's gone.
359 void NaClAddHostDescriptor(struct NaClApp
*nap
,
365 * Takes ownership of handle.
367 void NaClAddImcHandle(struct NaClApp
*nap
,
371 void NaClAddImcAddr(struct NaClApp
*nap
,
372 struct NaClSocketAddress
const *addr
,
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
382 int NaClCreateMainThread(struct NaClApp
*nap
,
387 int NaClWaitForMainThreadToExit(struct NaClApp
*nap
);
390 * Used by syscall code.
392 int32_t NaClCreateAdditionalThread(struct NaClApp
*nap
,
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
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
,
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
,
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
,
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
,
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
,
494 if (0 == uaddr
|| uaddr
>= (1U << nap
->addr_bits
)) {
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
,
505 if (sysaddr
< nap
->mem_start
||
506 sysaddr
>= nap
->mem_start
+ (1U << nap
->addr_bits
)) {
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
521 struct NaClDesc
*NaClGetDesc(struct NaClApp
*nap
,
525 * Takes ownership of ndp.
527 void NaClSetDesc(struct NaClApp
*nap
,
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
,
541 void NaClSetDescMu(struct NaClApp
*nap
,
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
,
558 void NaClRemoveThreadMu(struct NaClApp
*nap
,
561 struct NaClAppThread
*NaClGetThreadMu(struct NaClApp
*nap
,
564 void NaClAppVmmapUpdate(struct NaClApp
*nap
,
568 struct NaClMemObj
*nmop
,
571 uintptr_t NaClAppVmmapFindSpace(struct NaClApp
*nap
,
574 uintptr_t NaClAppVmmapFindMapSpace(struct NaClApp
*nap
,
577 void NaClCreateServiceSocket(struct NaClApp
*nap
);
579 void NaClSendServiceAddressTo(struct NaClApp
*nap
,
582 void NaClDumpServiceAddressTo(struct NaClApp
*nap
,