Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / native_client / src / trusted / service_runtime / sel_ldr.h
1 /*
2  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6
7 /*
8  * NaCl Simple/secure ELF loader (NaCl SEL).
9  *
10  * This loader can only process NaCl object files as produced using
11  * the NaCl toolchain.  Other ELF files will be rejected.
12  *
13  * The primary function, NaClAppLoadFile, parses an ELF file,
14  * allocates memory, loads the relocatable image from the ELF file
15  * into memory, and performs relocation.  NaClAppRun runs the
16  * resultant program.
17  *
18  * This loader is written in C so that it can be used by C-only as
19  * well as C++ applications.  Other languages should also be able to
20  * use their foreign-function interfaces to invoke C code.
21  *
22  * This loader must be part of the NaCl TCB, since it directly handles
23  * externally supplied input (the ELF file).  Any security
24  * vulnerabilities in handling the ELF image, e.g., buffer or integer
25  * overflows, can put the application at risk.
26  */
27
28 #ifndef NATIVE_CLIENT_SRC_TRUSTED_SERVICE_RUNTIME_SEL_LDR_H_
29 #define NATIVE_CLIENT_SRC_TRUSTED_SERVICE_RUNTIME_SEL_LDR_H_ 1
30
31 #include "native_client/src/include/atomic_ops.h"
32 #include "native_client/src/include/nacl_base.h"
33 #include "native_client/src/include/portability.h"
34 #include "native_client/src/include/elf.h"
35
36 #include "native_client/src/public/nacl_app.h"
37
38 #include "native_client/src/shared/platform/nacl_host_desc.h"
39 #include "native_client/src/shared/platform/nacl_log.h"
40 #include "native_client/src/shared/platform/nacl_threads.h"
41
42 #include "native_client/src/shared/srpc/nacl_srpc.h"
43
44 #include "native_client/src/trusted/interval_multiset/nacl_interval_multiset.h"
45 #include "native_client/src/trusted/interval_multiset/nacl_interval_range_tree.h"
46
47 #include "native_client/src/trusted/service_runtime/dyn_array.h"
48 #include "native_client/src/trusted/service_runtime/nacl_error_code.h"
49 #include "native_client/src/trusted/service_runtime/nacl_kernel_service.h"
50 #include "native_client/src/trusted/service_runtime/nacl_resource.h"
51 #include "native_client/src/trusted/service_runtime/nacl_secure_service.h"
52 #include "native_client/src/trusted/service_runtime/name_service/name_service.h"
53 #include "native_client/src/trusted/service_runtime/sel_addrspace.h"
54 #include "native_client/src/trusted/service_runtime/sel_mem.h"
55 #include "native_client/src/trusted/service_runtime/sel_rt.h"
56 #include "native_client/src/trusted/service_runtime/sel_util.h"
57 #include "native_client/src/trusted/service_runtime/sys_futex.h"
58
59 #include "native_client/src/trusted/validator/ncvalidate.h"
60
61 EXTERN_C_BEGIN
62
63 #define NACL_SERVICE_PORT_DESCRIPTOR    3
64 #define NACL_SERVICE_ADDRESS_DESCRIPTOR 4
65
66 #define NACL_DEFAULT_STACK_MAX  (16 << 20)  /* main thread stack */
67
68 struct NaClAppThread;
69 struct NaClDesc;  /* see native_client/src/trusted/desc/nacl_desc_base.h */
70 struct NaClDynamicRegion;
71 struct NaClRuntimeHostInterface;
72 struct NaClDescQuotaInterface;
73 struct NaClSignalContext;
74 struct NaClThreadInterface;  /* see sel_ldr_thread_interface.h */
75 struct NaClValidationCache;
76 struct NaClValidationMetadata;
77
78 struct NaClDebugCallbacks {
79   void (*thread_create_hook)(struct NaClAppThread *natp);
80   void (*thread_exit_hook)(struct NaClAppThread *natp);
81   void (*process_exit_hook)(void);
82 };
83
84 enum NaClResourcePhase {
85   NACL_RESOURCE_PHASE_START,
86   NACL_RESOURCE_PHASE_RUNTIME_HOST
87 };
88
89 #if NACL_WINDOWS
90 enum NaClDebugExceptionHandlerState {
91   NACL_DEBUG_EXCEPTION_HANDLER_NOT_STARTED,
92   NACL_DEBUG_EXCEPTION_HANDLER_STARTED,
93   NACL_DEBUG_EXCEPTION_HANDLER_FAILED
94 };
95 /*
96  * Callback function used to request that an exception handler be
97  * attached using the Windows debug API.  See sel_main_chrome.h.
98  */
99 typedef int (*NaClAttachDebugExceptionHandlerFunc)(const void *info,
100                                                    size_t size);
101 #endif
102
103 struct NaClSpringboardInfo {
104   /* These are addresses in untrusted address space (relative to mem_start). */
105   uint32_t start_addr;
106   uint32_t end_addr;
107 };
108
109 struct NaClApp {
110   /*
111    * public, user settable prior to app start.
112    */
113   uint8_t                   addr_bits;
114   uintptr_t                 stack_size;
115   uint32_t                  initial_nexe_max_code_bytes;
116   /*
117    * stack_size is the maximum size of the (main) stack.  The stack
118    * memory is eager allocated (mapped in w/o MAP_NORESERVE) so
119    * there must be enough swap space; page table entries are not
120    * populated (no MAP_POPULATE), so actual accesses will likely
121    * incur page faults.
122    */
123
124   /*
125    * Determined at load time; OS-determined.
126    * Read-only after load, so accesses do not require locking.
127    */
128   uintptr_t                 mem_start;
129
130 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
131   uintptr_t                 pcrel_thunk;
132   uintptr_t                 pcrel_thunk_end;
133 #endif
134 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
135   uintptr_t                 nacl_syscall_addr;
136   uintptr_t                 get_tls_fast_path1_addr;
137   uintptr_t                 get_tls_fast_path2_addr;
138 #endif
139
140   /* only used for ET_EXEC:  for CS restriction */
141   uintptr_t                 static_text_end;
142   /*
143    * relative to mem_start; ro after app starts. memsz from phdr
144    */
145
146   /*
147    * The dynamic code area follows the static code area.  These fields
148    * are both set to static_text_end if the dynamic code area has zero
149    * size.
150    */
151   uintptr_t                 dynamic_text_start;
152   uintptr_t                 dynamic_text_end;
153
154   /*
155    * rodata_start and data_start may be 0 if these segments are not
156    * present in the executable.
157    */
158   uintptr_t                 rodata_start;  /* initialized data, ro */
159   uintptr_t                 data_start;    /* initialized data/bss, rw */
160   /*
161    * Various region sizes must be a multiple of NACL_MAP_PAGESIZE
162    * before the NaCl app can run.  The sizes from the ELF file
163    * (p_filesz field) might not be -- that would waste space for
164    * padding -- and while we could use p_memsz to specify padding, but
165    * we will record the virtual addresses of the start of the segments
166    * and figure out the gap between the p_vaddr + p_filesz of one
167    * segment and p_vaddr of the next to determine padding.
168    */
169
170   uintptr_t                 data_end;
171   /* see break_addr below */
172
173   /*
174    * initial_entry_pt is the first address in untrusted code to jump
175    * to.  When using the IRT (integrated runtime), this is provided by
176    * the IRT library, and user_entry_pt is the entry point in the user
177    * executable.  Otherwise, initial_entry_pt is in the user
178    * executable and user_entry_pt is zero.
179    */
180   uintptr_t                 initial_entry_pt;
181   uintptr_t                 user_entry_pt;
182
183   /*
184    * bundle_size is the bundle alignment boundary for validation (16
185    * or 32), so int is okay.  This value must be a power of 2.
186    */
187   int                       bundle_size;
188
189   /* common to both ELF executables and relocatable load images */
190
191 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
192   /* Addresses of trusted springboard code for switching to untrusted code. */
193   struct NaClSpringboardInfo syscall_return_springboard;
194   struct NaClSpringboardInfo all_regs_springboard;
195 #endif
196
197   /*
198    * The socket at which the app should be accepting connections.  The
199    * corresponding socket address are made available by the JavaScript
200    * bridge to other NaCl modules.
201    */
202   struct NaClDesc           *service_port;
203   struct NaClDesc           *service_address;
204
205   struct NaClDesc           *secure_service_port;
206   struct NaClDesc           *secure_service_address;
207
208   struct NaClDesc           *bootstrap_channel;
209
210   /*
211    * The IRT may be supplied by an SRPC call via the command channel,
212    * or by the irt_fd member in struct NaClChromeMainArgs in the case
213    * of sel_main_chrome (the embedded service runtime), or by the -B
214    * command line argument in the case of sel_main (the standalone
215    * service runtime process).  We let the command channel have
216    * priority.
217    */
218   int irt_loaded;  /* bool */
219
220   /*
221    * The main NaCl executable may already be validated during ELF
222    * loading, where after a validation cache hit the code gets mmapped
223    * into memory if the file descriptor is "blessed" as referring to a
224    * file which the embedding environment guarantees to be effectively
225    * immutable.  If it did not validate or the file descriptor is not
226    * blessed, then the code is read into memory, and we will validate
227    * it later in the code path, in NaClAppLoadFileAslr.
228    */
229   int main_exe_prevalidated;  /* bool */
230
231   struct NaClMutex          mu;
232   struct NaClCondVar        cv;
233
234 #if NACL_WINDOWS
235   /*
236    * invariant: !(vm_hole_may_exist && threads_launching != 0).
237    * vm_hole_may_exist is set while mmap/munmap manipulates the memory
238    * map, and threads_launching is set while a thread is launching
239    * (and a trusted thread stack is being allocated).
240    *
241    * strictly speaking, vm_hole_may_exist need not be present, since
242    * the vm code ensures that 0 == threads_launching and then holds
243    * the lock for the duration of the VM operation.  it is safer this
244    * way, in case we later introduce code that might want to
245    * temporarily drop the process lock.
246    */
247   int                       vm_hole_may_exist;
248   int                       threads_launching;
249 #endif
250
251   /*
252    * An array of NaCl syscall handlers. The length of the array must be
253    * at least NACL_MAX_SYSCALLS.
254    */
255   struct NaClSyscallTableEntry *syscall_table;
256
257   /*
258    * Name service must launch after mu, cv, vm_hole_may_exit,
259    * threads_launching are initialized.
260    */
261   struct NaClNameService    *name_service;  /* default name server */
262   struct NaClDesc           *name_service_conn_cap;
263
264   struct NaClSecureService          *secure_service;
265
266   struct NaClKernelService          *kernel_service;
267
268   struct NaClResourceNaClApp        resources;
269   enum NaClResourcePhase            resource_phase;
270
271   struct NaClRuntimeHostInterface   *runtime_host_interface;
272   struct NaClDescQuotaInterface     *desc_quota_interface;
273
274   /*
275    * The ordering in this enum is important. We use the ordering
276    * to check that the status of module initialization; the state
277    * is really being used as a state machine. Please do not change
278    * the ordering, if you need to add a new state please do so at
279    * the appropriate position dependending on a module loading phase.
280    */
281
282   enum NaClModuleInitializationState {
283     NACL_MODULE_UNINITIALIZED = 0,
284     NACL_MODULE_LOADING,
285     NACL_MODULE_LOADED,
286     NACL_MODULE_STARTING,
287     NACL_MODULE_STARTED,
288     NACL_MODULE_ERROR
289   }                                 module_initialization_state;
290   NaClErrorCode                     module_load_status;
291
292   /*
293    * runtime info below, thread state, etc; initialized only when app
294    * is run.  Mutex mu protects access to mem_map and other member
295    * variables while the application is running and may be
296    * multithreaded; thread, desc members have their own locks.  At
297    * other times it is assumed that only one thread is
298    * constructing/loading the NaClApp and that no mutual exclusion is
299    * needed.
300    */
301
302   /*
303    * memory map is in user addresses.
304    */
305   struct NaClVmmap          mem_map;
306
307   struct NaClIntervalMultiset *mem_io_regions;
308
309   /*
310    * This is the effector interface object that is used to manipulate
311    * NaCl apps by the objects in the NaClDesc class hierarchy.  This
312    * is used by this NaClApp when making NaClDesc method calls from
313    * syscall handlers.  Currently, this is when NaClDesc objects need
314    * to manipulate the untrusted address space -- the mmap
315    * implementation need to unmap the untrusted pages, and on Windows
316    * this requires different calls depending on how the pages were
317    * created.
318    */
319   struct NaClDescEffector   *effp;
320
321   /*
322    * may reject nexes that are incompatible w/ dynamic-text in the near future
323    */
324   int                       enable_dyncode_syscalls;
325   int                       use_shm_for_dynamic_text;
326   struct NaClDesc           *text_shm;
327   struct NaClMutex          dynamic_load_mutex;
328   /*
329    * This records which pages in text_shm have been allocated.  When a
330    * page is allocated, it is filled with halt instructions and then
331    * made executable by untrusted code.
332    */
333   uint8_t                   *dynamic_page_bitmap;
334
335   /*
336    * The array of dynamic_regions is maintained in sorted order
337    * Accesses must be protected by dynamic_load_mutex.
338    */
339   struct NaClDynamicRegion  *dynamic_regions;
340   int                       num_dynamic_regions;
341   int                       dynamic_regions_allocated;
342
343   /*
344    * These variables are used for caching mapped writable views of the
345    * dynamic text segment.  See CachedMapWritableText in nacl_text.c.
346    * Accesses must be protected by dynamic_load_mutex
347    */
348   uint32_t                  dynamic_mapcache_offset;
349   uint32_t                  dynamic_mapcache_size;
350   uintptr_t                 dynamic_mapcache_ret;
351
352   /*
353    * Monotonically increasing generation number used for deletion
354    * Accesses must be protected by dynamic_load_mutex
355    */
356   int                       dynamic_delete_generation;
357
358
359   int                       running;
360   int                       exit_status;
361
362   NaClCPUFeatures           *cpu_features;
363   int                       fixed_feature_cpu_mode;
364   struct NaClValidationCache *validation_cache;
365   int                       ignore_validator_result;
366   int                       skip_validator;
367   int                       validator_stub_out_mode;
368
369   int                       enable_list_mappings;
370   /* Whether or not the app is a PNaCl app.  Boolean. */
371   int                       pnacl_mode;
372
373 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
374   uint16_t                  code_seg_sel;
375   uint16_t                  data_seg_sel;
376 #endif
377
378   uintptr_t                 break_addr;   /* user addr */
379   /* data_end <= break_addr is an invariant */
380
381   /*
382    * Thread table lock threads_mu is higher in the locking order than
383    * the thread locks, i.e., threads_mu must be acqured w/o holding
384    * any per-thread lock (natp->mu).
385    */
386   struct NaClMutex          threads_mu;
387   struct DynArray           threads;   /* NaClAppThread pointers */
388   int                       num_threads;  /* number actually running */
389
390   struct NaClFastMutex      desc_mu;
391   struct DynArray           desc_tbl;  /* NaClDesc pointers */
392
393   const struct NaClDebugCallbacks *debug_stub_callbacks;
394 #if NACL_WINDOWS
395   uint16_t                        debug_stub_port;
396 #endif
397   struct NaClDesc                 *main_nexe_desc;
398   struct NaClDesc                 *irt_nexe_desc;
399
400   struct NaClMutex          exception_mu;
401   uint32_t                  exception_handler;
402   int                       enable_exception_handling;
403 #if NACL_WINDOWS
404   enum NaClDebugExceptionHandlerState debug_exception_handler_state;
405   NaClAttachDebugExceptionHandlerFunc attach_debug_exception_handler_func;
406 #endif
407   /*
408    * enable_faulted_thread_queue is a boolean which enables handling
409    * of untrusted faults which is used by the debug stub.  When an
410    * untrusted thread faults, it is blocked until
411    * NaClAppThreadUnblockIfFaulted() is called on the thread.
412    */
413   int                       enable_faulted_thread_queue;
414   /*
415    * faulted_thread_count is the number of NaClAppThreads for which
416    * fault_signal is non-zero.
417    */
418   Atomic32                  faulted_thread_count;
419 #if NACL_WINDOWS
420   /*
421    * An event that is signaled by debug exception handler process when it fills
422    * fault_signal field with non-zero value for some NaClAppThread.
423    */
424   HANDLE                    faulted_thread_event;
425 #else
426   /*
427    * A file descriptor of a pipe which becomes available for reading in
428    * the event that fault_signal for some NaClAppThread becomes non-zero.
429    */
430   int                       faulted_thread_fd_read;
431   int                       faulted_thread_fd_write;
432 #endif
433
434   /*
435    * Cache of sysconf(_SC_NPROCESSORS_ONLN) (or equivalent) result.
436    */
437   int sc_nprocessors_onln;
438
439   const struct NaClValidatorInterface *validator;
440
441   /*
442    * Mutex for protecting futex_wait_list_head.  Lock ordering:
443    * NaClApp::mu may be claimed after futex_wait_list_mu but never
444    * before it.
445    */
446   struct NaClMutex          futex_wait_list_mu;
447   /*
448    * This is the sentinel node for a doubly linked list of
449    * NaClAppThreads.  This lists the threads that are waiting to be
450    * woken up by futex_wake().  This list must only be accessed while
451    * holding the mutex futex_wait_list_mu.
452    */
453   struct NaClListNode       futex_wait_list_head;
454 };
455
456
457
458 void  NaClAppIncrVerbosity(void);
459
460 /*
461  * Initializes a NaCl application with the default parameters
462  * and the specified syscall table.
463  *
464  * If invoked after the outer sandbox is enabled, the caller is
465  * responsible for initializing the sc_nprocessors_onln member to a
466  * sane value.
467  *
468  * nap is a pointer to the NaCl object that is being filled in.
469  *
470  * table is the NaCl syscall table. The syscall table must contain at least
471  * NACL_MAX_SYSCALLS valid entries.
472  *
473  * Caution! Syscall handlers must be extremely careful with respect to
474  * argument validation, including time-of-check vs time-of-use defense, etc.
475  */
476 int NaClAppWithSyscallTableCtor(struct NaClApp               *nap,
477                                 struct NaClSyscallTableEntry *table) NACL_WUR;
478 /*
479  * Standard Ctor for NaClApp objects.  Installs default syscall
480  * handlers.
481  *
482  * If invoked after the outer sandbox is enabled, the caller is
483  * responsible for initializing the sc_nprocessors_onln member to a
484  * sane value.
485  *
486  * nap is a pointer to the NaCl object that is being filled in.
487  */
488 int NaClAppCtor(struct NaClApp  *nap) NACL_WUR;
489
490 /*
491  * Loads a NaCl ELF file into memory in preparation for running it.
492  *
493  * gp is a pointer to a generic I/O object and should be a GioMem with
494  * a memory buffer containing the file read entirely into memory if
495  * the file system might be subject to race conditions (e.g., another
496  * thread / process might modify a downloaded NaCl ELF file while we
497  * are loading it here).
498  *
499  * nap is a pointer to the NaCl object that is being filled in.  it
500  * should be properly constructed via NaClAppCtor.
501  *
502  * return value: one of the LOAD_* values defined in
503  * nacl_error_code.h.  TODO: add some error detail string and hang
504  * that off the nap object, so that more details are available w/o
505  * incrementing verbosity (and polluting stdout).
506  *
507  * note: it may be necessary to flush the icache if the memory
508  * allocated for use had already made it into the icache from another
509  * NaCl application instance, and the icache does not detect
510  * self-modifying code / data writes and automatically invalidate the
511  * cache lines.
512  */
513 NaClErrorCode NaClAppLoadFile(struct NaClDesc *ndp,
514                               struct NaClApp *nap) NACL_WUR;
515
516 /*
517  * Just like NaClAppLoadFile, but allow control over ASLR.
518  */
519 NaClErrorCode NaClAppLoadFileAslr(struct NaClDesc *ndp,
520                                   struct NaClApp *nap,
521                                   enum NaClAslrMode aslr_mode) NACL_WUR;
522
523
524 NaClErrorCode NaClAppLoadFileDynamically(
525     struct NaClApp *nap,
526     struct NaClDesc *ndp,
527     struct NaClValidationMetadata *metadata) NACL_WUR;
528
529 void  NaClAppPrintDetails(struct NaClApp  *nap,
530                           struct Gio      *gp);
531
532 NaClErrorCode NaClLoadImage(struct Gio            *gp,
533                             struct NaClApp        *nap) NACL_WUR;
534
535 int NaClValidateCode(struct NaClApp *nap,
536                      uintptr_t      guest_addr,
537                      uint8_t        *data,
538                      size_t         size,
539                      const struct NaClValidationMetadata *metadata) NACL_WUR;
540
541 /*
542  * Validates that the code found at data_old can safely be replaced with
543  * the code found at data_new.
544  */
545 int NaClValidateCodeReplacement(struct    NaClApp *nap,
546                                 uintptr_t guest_addr,
547                                 uint8_t   *data_old,
548                                 uint8_t   *data_new,
549                                 size_t    size);
550
551 /*
552  * Copies code from data_new to data_old in a thread-safe way.
553  */
554 int NaClCopyCode(struct NaClApp *nap, uintptr_t guest_addr,
555                  uint8_t *data_old, uint8_t *data_new,
556                  size_t size);
557
558 /*
559  * Copies an instruction in a thread-safe way. Used by validators.
560  */
561 int NaClCopyInstruction(uint8_t *dst, uint8_t *src, uint8_t sz);
562
563 NaClErrorCode NaClValidateImage(struct NaClApp  *nap) NACL_WUR;
564
565
566 int NaClAddrIsValidEntryPt(struct NaClApp *nap,
567                            uintptr_t      addr);
568
569 /*
570  * Takes ownership of descriptor, i.e., when NaCl app closes, it's gone.
571  */
572 void NaClAddHostDescriptor(struct NaClApp *nap,
573                            int            host_os_desc,
574                            int            mode,
575                            int            nacl_desc);
576
577 /*
578  * Takes ownership of handle.
579  */
580 void NaClAddImcHandle(struct NaClApp  *nap,
581                       NaClHandle      h,
582                       int             nacl_desc);
583
584 /*
585  * Launch system-level service threads.  After this, access to the
586  * NaClApp object must be done in a thread-safe manner, using nap->mu
587  * etc, or access only read-only data.
588  *
589  * NB: the "secure command channel" thread should have already started
590  * (if enabled); that thread must take care to not race with the main
591  * thread that is continuing to set up the NaCl module as well.
592  */
593 int NaClAppLaunchServiceThreads(struct NaClApp *nap);
594
595 /*
596  * Report the low eight bits of |exit_status| via the reverse channel
597  * in |nap|, if one exists, to whomever is interested.  This usually
598  * involves an RPC.  Returns true if successfully reported.
599  *
600  * Also mark nap's exit_status and running member variables, announce
601  * via condvar that the nexe should be considered no longer running.
602  *
603  * Returns true (non-zero) if exit status was reported via the reverse
604  * channel, and false (0) otherwise.
605  */
606 int NaClReportExitStatus(struct NaClApp *nap, int exit_status);
607
608 /*
609  * Get the top of the initial thread's stack.  Returns a user address.
610  */
611 uintptr_t NaClGetInitialStackTop(struct NaClApp *nap);
612
613 /*
614  * Used to launch the main thread.  NB: calling thread may in the
615  * future become the main NaCl app thread, and this function will
616  * return only after the NaCl app main thread exits.  In such an
617  * alternative design, NaClWaitForMainThreadToExit will become a
618  * no-op.
619  */
620 int NaClCreateMainThread(struct NaClApp     *nap,
621                          int                argc,
622                          char               **argv,
623                          char const *const  *envp) NACL_WUR;
624
625 int NaClWaitForMainThreadToExit(struct NaClApp  *nap);
626
627 /*
628  * Used by syscall code.
629  */
630 int32_t NaClCreateAdditionalThread(struct NaClApp *nap,
631                                    uintptr_t      prog_ctr,
632                                    uintptr_t      stack_ptr,
633                                    uint32_t       user_tls1,
634                                    uint32_t       user_tls2) NACL_WUR;
635
636 void NaClLoadTrampoline(struct NaClApp *nap, enum NaClAslrMode aslr_mode);
637
638 void NaClLoadSpringboard(struct NaClApp  *nap);
639
640 static const uintptr_t kNaClBadAddress = (uintptr_t) -1;
641
642 #include "native_client/src/trusted/service_runtime/sel_ldr-inl.h"
643
644 /*
645  * Looks up a descriptor in the open-file table.  An additional
646  * reference is taken on the returned NaClDesc object (if non-NULL).
647  * The caller is responsible for invoking NaClDescUnref() on it when
648  * done.
649  */
650 struct NaClDesc *NaClAppGetDesc(struct NaClApp *nap,
651                                 int            d);
652
653 /* NaClAppSetDesc() is defined in src/public/chrome_main.h. */
654
655 int32_t NaClAppSetDescAvail(struct NaClApp   *nap,
656                             struct NaClDesc  *ndp);
657
658 /*
659  * Versions that are called while already holding the desc_mu lock
660  */
661 struct NaClDesc *NaClAppGetDescMu(struct NaClApp *nap,
662                                   int            d);
663
664 void NaClAppSetDescMu(struct NaClApp   *nap,
665                       int              d,
666                       struct NaClDesc  *ndp);
667
668 int32_t NaClAppSetDescAvailMu(struct NaClApp   *nap,
669                               struct NaClDesc  *ndp);
670
671
672 int NaClAddThread(struct NaClApp        *nap,
673                   struct NaClAppThread  *natp);
674
675 int NaClAddThreadMu(struct NaClApp        *nap,
676                     struct NaClAppThread  *natp);
677
678 void NaClRemoveThread(struct NaClApp  *nap,
679                       int             thread_num);
680
681 void NaClRemoveThreadMu(struct NaClApp  *nap,
682                         int             thread_num);
683
684 struct NaClAppThread *NaClGetThreadMu(struct NaClApp  *nap,
685                                       int             thread_num);
686
687 void NaClAppInitialDescriptorHookup(struct NaClApp  *nap);
688
689 void NaClCreateServiceSocket(struct NaClApp *nap);
690
691 void NaClSetUpBootstrapChannel(struct NaClApp  *nap,
692                                NaClHandle      inherited_desc);
693
694 void NaClSecureCommandChannel(struct NaClApp  *nap);
695
696 /*
697  * Loads the |nexe| as a NaCl app module.
698  * The |load_cb| callback is invoked before the the |nexe| is loaded to allow
699  * validation being run in parallel.
700  */
701 void NaClAppLoadModule(struct NaClApp      *self,
702                        struct NaClDesc     *nexe,
703                        void                (*load_cb)(void *instance_data,
704                                                       NaClErrorCode status),
705                        void                *instance_data);
706
707 int NaClAppRuntimeHostSetup(struct NaClApp                  *self,
708                             struct NaClRuntimeHostInterface *host_itf);
709
710 int NaClAppDescQuotaSetup(struct NaClApp                *self,
711                           struct NaClDescQuotaInterface *rev_quota);
712
713 /*
714  * Starts the NaCl app, the |start_cb| callback is invoked before the
715  * application is actually started.
716  */
717 void NaClAppStartModule(struct NaClApp  *self,
718                         void            (*start_cb)(void *instance_data,
719                                                     NaClErrorCode status),
720                         void            *instance_data);
721
722 void NaClAppShutdown(struct NaClApp     *self,
723                      int                exit_status);
724
725 NaClErrorCode NaClWaitForLoadModuleCommand(struct NaClApp *nap) NACL_WUR;
726
727 NaClErrorCode NaClWaitForLoadModuleStatus(struct NaClApp *nap) NACL_WUR;
728
729 NaClErrorCode NaClWaitForStartModuleCommand(struct NaClApp *nap) NACL_WUR;
730
731 /*
732  * NaClBlockIfCommandChannelExists is used during error exit.  If
733  * there is a secure command channel, we sent an RPC reply with the
734  * reason that the nexe was rejected.  If we exit immediately, that
735  * reply may still be in-flight and the various channel closure (esp
736  * reverse channels, if those were set up) may be detected first by
737  * the controlling process on the other end of the command channel or
738  * reverse channel.  When channel closure wins the race against the
739  * RPC reply, it would result in a crash being reported, rather than
740  * the error code carried in the RPC reply.  We want to ensure that
741  * the RPC reply to get processed.  Instead of allowing the service
742  * runtime process to exit, we block the main thread and wait for the
743  * hard-shutdown on the command channel or command channel closure.
744  *
745  * If there is no command channel, NaClBlockIfCommandChannelExists
746  * just returns immediately.
747  */
748 void NaClBlockIfCommandChannelExists(struct NaClApp *nap);
749
750 void NaClFillMemoryRegionWithHalt(void *start, size_t size);
751
752 void NaClFillTrampolineRegion(struct NaClApp *nap);
753
754 void NaClFillEndOfTextRegion(struct NaClApp *nap);
755
756 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
757
758 int NaClMakePcrelThunk(struct NaClApp *nap, enum NaClAslrMode aslr_mode);
759
760 #endif
761
762 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
763
764 int NaClMakeDispatchAddrs(struct NaClApp *nap);
765
766 void NaClPatchOneTrampolineCall(uintptr_t call_target_addr,
767                                 uintptr_t target_addr);
768
769 #endif
770
771 void NaClPatchOneTrampoline(struct NaClApp *nap,
772                             uintptr_t target_addr);
773 /*
774  * target is an absolute address in the source region.  the patch code
775  * will figure out the corresponding address in the destination region
776  * and modify as appropriate.  this makes it easier to specify, since
777  * the target is typically the address of some symbol from the source
778  * template.
779  */
780 struct NaClPatch {
781   uintptr_t           target;
782   uint64_t            value;
783 };
784
785 struct NaClPatchInfo {
786   uintptr_t           dst;
787   uintptr_t           src;
788   size_t              nbytes;
789
790   struct NaClPatch    *abs16;
791   size_t              num_abs16;
792
793   struct NaClPatch    *abs32;
794   size_t              num_abs32;
795
796   struct NaClPatch    *abs64;
797   size_t              num_abs64;
798
799 #if NACL_TARGET_SUBARCH == 32
800   uintptr_t           *rel32;
801   size_t              num_rel32;
802 #endif
803
804   uintptr_t           *rel64;
805   size_t              num_rel64;
806 };
807
808 struct NaClPatchInfo *NaClPatchInfoCtor(struct NaClPatchInfo *self);
809
810 void NaClApplyPatchToMemory(struct NaClPatchInfo *patch);
811
812 int NaClAppThreadInitArchSpecific(struct NaClAppThread *natp,
813                                   nacl_reg_t           prog_ctr,
814                                   nacl_reg_t           stack_ptr);
815
816 void NaClVmHoleWaitToStartThread(struct NaClApp *nap);
817
818 void NaClVmHoleThreadStackIsSafe(struct NaClApp *nap);
819
820 void NaClVmHoleOpeningMu(struct NaClApp *nap);
821
822 void NaClVmHoleClosingMu(struct NaClApp *nap);
823
824 /*
825  * More VM race detection.  In Windows, when we unmap or mmap over
826  * existing memory, we cannot maintain the address space reservation
827  * -- we have to unmap the original mapping with the appropriate
828  * unmapping function (VirtualFree or UnmapViewOfFile) before we can
829  * VirtualAlloc to reserve the addresss pace, leaving a timing window
830  * where another thread (possibly injected into the binary, e.g.,
831  * antivirus code) might map something else into.  We stop user-space
832  * threads when mmap/munmap occurs and detect if the temporary VM hole
833  * was filled by some other thread (and abort the process in that
834  * case), so that untrusted code cannot observe nor modify the memory
835  * that lands in the hole.  However, we still have the case where the
836  * untrusted code's threads aren't running user-space code -- a thread
837  * may have entered into a syscall handler.  We don't stop such
838  * threads, because they might be holding locks that the memory
839  * mapping functions need.  This means that, for example, a malicious
840  * application could -- assuming it could create the innocent thread
841  * race condition -- have one thread invoke the "write" NaCl syscall,
842  * enter into the host OS "write" syscall code in the NaCl syscall
843  * handler, then have another thread mmap (or munmap) the memory where
844  * the source memory region from which the content to be written
845  * resides, and as a side effect of this race, exfiltrate memory
846  * contents that NaCl modules aren't supposed to be able to access.
847  *
848  * NB: we do not try to prevent data races such as two "read" syscalls
849  * simultaneously trying to write the same memory region, or
850  * concurrent "read" and "write" syscalls racing on the same memory
851  * region..
852  */
853
854 /*
855  * Some potentially blocking I/O operation is about to start.  Syscall
856  * handlers implement DMA-style access where the host-OS syscalls
857  * directly read/write untrusted memory, so we must record the
858  * affected memory ranges as "in use" by I/O operations.
859  */
860 void NaClVmIoWillStart(struct NaClApp *nap,
861                        uint32_t addr_first_usr,
862                        uint32_t addr_last_usr);
863
864
865 /*
866  * It is a fatal error to have an invocation of NaClVmIoHasEnded whose
867  * arguments do not match those of an earlier, unmatched invocation of
868  * NaClVmIoWillStart.
869  */
870 void NaClVmIoHasEnded(struct NaClApp *nap,
871                       uint32_t addr_first_usr,
872                       uint32_t addr_last_usr);
873
874 /*
875  * Used by operations (mmap, munmap) that will open a VM hole.
876  * Invoked while holding the VM lock.  Check that no I/O is pending;
877  * abort the app if the app is racing I/O operations against VM
878  * operations.
879  */
880 void NaClVmIoPendingCheck_mu(struct NaClApp *nap,
881                              uint32_t addr_first_usr,
882                              uint32_t addr_last_usr);
883
884 void NaClGdbHook(struct NaClApp const *nap);
885
886 #if NACL_LINUX
887 void NaClHandleBootstrapArgs(int *argc_p, char ***argv_p);
888 void NaClHandleRDebug(const char *switch_value, char *argv0);
889 void NaClHandleReservedAtZero(const char *switch_value);
890 #else
891 static INLINE void NaClHandleBootstrapArgs(int *argc_p, char ***argv_p) {
892   UNREFERENCED_PARAMETER(argc_p);
893   UNREFERENCED_PARAMETER(argv_p);
894 }
895 #endif
896
897 EXTERN_C_END
898
899 #endif  /* NATIVE_CLIENT_SRC_TRUSTED_SERVICE_RUNTIME_SEL_LDR_H_ */