Upstream version 9.38.198.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 main NaCl executable may already be validated during ELF
212    * loading, where after a validation cache hit the code gets mmapped
213    * into memory if the file descriptor is "blessed" as referring to a
214    * file which the embedding environment guarantees to be effectively
215    * immutable.  If it did not validate or the file descriptor is not
216    * blessed, then the code is read into memory, and we will validate
217    * it later in the code path, in NaClAppLoadFileAslr.
218    */
219   int main_exe_prevalidated;  /* bool */
220
221   struct NaClMutex          mu;
222   struct NaClCondVar        cv;
223
224 #if NACL_WINDOWS
225   /*
226    * invariant: !(vm_hole_may_exist && threads_launching != 0).
227    * vm_hole_may_exist is set while mmap/munmap manipulates the memory
228    * map, and threads_launching is set while a thread is launching
229    * (and a trusted thread stack is being allocated).
230    *
231    * strictly speaking, vm_hole_may_exist need not be present, since
232    * the vm code ensures that 0 == threads_launching and then holds
233    * the lock for the duration of the VM operation.  it is safer this
234    * way, in case we later introduce code that might want to
235    * temporarily drop the process lock.
236    */
237   int                       vm_hole_may_exist;
238   int                       threads_launching;
239 #endif
240
241   /*
242    * An array of NaCl syscall handlers. The length of the array must be
243    * at least NACL_MAX_SYSCALLS.
244    */
245   struct NaClSyscallTableEntry *syscall_table;
246
247   /*
248    * Name service must launch after mu, cv, vm_hole_may_exit,
249    * threads_launching are initialized.
250    */
251   struct NaClNameService    *name_service;  /* default name server */
252   struct NaClDesc           *name_service_conn_cap;
253
254   struct NaClSecureService          *secure_service;
255
256   struct NaClKernelService          *kernel_service;
257
258   struct NaClResourceNaClApp        resources;
259   enum NaClResourcePhase            resource_phase;
260
261   struct NaClRuntimeHostInterface   *runtime_host_interface;
262   struct NaClDescQuotaInterface     *desc_quota_interface;
263
264   /*
265    * The ordering in this enum is important. We use the ordering
266    * to check that the status of module initialization; the state
267    * is really being used as a state machine. Please do not change
268    * the ordering, if you need to add a new state please do so at
269    * the appropriate position dependending on a module loading phase.
270    */
271
272   enum NaClModuleInitializationState {
273     NACL_MODULE_UNINITIALIZED = 0,
274     NACL_MODULE_LOADING,
275     NACL_MODULE_LOADED,
276     NACL_MODULE_STARTING,
277     NACL_MODULE_STARTED,
278     NACL_MODULE_ERROR
279   }                                 module_initialization_state;
280   NaClErrorCode                     module_load_status;
281
282   /*
283    * runtime info below, thread state, etc; initialized only when app
284    * is run.  Mutex mu protects access to mem_map and other member
285    * variables while the application is running and may be
286    * multithreaded; thread, desc members have their own locks.  At
287    * other times it is assumed that only one thread is
288    * constructing/loading the NaClApp and that no mutual exclusion is
289    * needed.
290    */
291
292   /*
293    * memory map is in user addresses.
294    */
295   struct NaClVmmap          mem_map;
296
297   struct NaClIntervalMultiset *mem_io_regions;
298
299   /*
300    * This is the effector interface object that is used to manipulate
301    * NaCl apps by the objects in the NaClDesc class hierarchy.  This
302    * is used by this NaClApp when making NaClDesc method calls from
303    * syscall handlers.  Currently, this is when NaClDesc objects need
304    * to manipulate the untrusted address space -- the mmap
305    * implementation need to unmap the untrusted pages, and on Windows
306    * this requires different calls depending on how the pages were
307    * created.
308    */
309   struct NaClDescEffector   *effp;
310
311   /*
312    * may reject nexes that are incompatible w/ dynamic-text in the near future
313    */
314   int                       enable_dyncode_syscalls;
315   int                       use_shm_for_dynamic_text;
316   struct NaClDesc           *text_shm;
317   struct NaClMutex          dynamic_load_mutex;
318   /*
319    * This records which pages in text_shm have been allocated.  When a
320    * page is allocated, it is filled with halt instructions and then
321    * made executable by untrusted code.
322    */
323   uint8_t                   *dynamic_page_bitmap;
324
325   /*
326    * The array of dynamic_regions is maintained in sorted order
327    * Accesses must be protected by dynamic_load_mutex.
328    */
329   struct NaClDynamicRegion  *dynamic_regions;
330   int                       num_dynamic_regions;
331   int                       dynamic_regions_allocated;
332
333   /*
334    * These variables are used for caching mapped writable views of the
335    * dynamic text segment.  See CachedMapWritableText in nacl_text.c.
336    * Accesses must be protected by dynamic_load_mutex
337    */
338   uint32_t                  dynamic_mapcache_offset;
339   uint32_t                  dynamic_mapcache_size;
340   uintptr_t                 dynamic_mapcache_ret;
341
342   /*
343    * Monotonically increasing generation number used for deletion
344    * Accesses must be protected by dynamic_load_mutex
345    */
346   int                       dynamic_delete_generation;
347
348
349   int                       running;
350   int                       exit_status;
351
352   NaClCPUFeatures           *cpu_features;
353   int                       fixed_feature_cpu_mode;
354   struct NaClValidationCache *validation_cache;
355   int                       ignore_validator_result;
356   int                       skip_validator;
357   int                       validator_stub_out_mode;
358
359   int                       enable_list_mappings;
360   /* Whether or not the app is a PNaCl app.  Boolean. */
361   int                       pnacl_mode;
362
363 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
364   uint16_t                  code_seg_sel;
365   uint16_t                  data_seg_sel;
366 #endif
367
368   uintptr_t                 break_addr;   /* user addr */
369   /* data_end <= break_addr is an invariant */
370
371   /*
372    * Thread table lock threads_mu is higher in the locking order than
373    * the thread locks, i.e., threads_mu must be acqured w/o holding
374    * any per-thread lock (natp->mu).
375    */
376   struct NaClMutex          threads_mu;
377   struct DynArray           threads;   /* NaClAppThread pointers */
378   int                       num_threads;  /* number actually running */
379
380   struct NaClFastMutex      desc_mu;
381   struct DynArray           desc_tbl;  /* NaClDesc pointers */
382
383   const struct NaClDebugCallbacks *debug_stub_callbacks;
384 #if NACL_WINDOWS
385   uint16_t                        debug_stub_port;
386 #endif
387   struct NaClDesc                 *main_nexe_desc;
388   struct NaClDesc                 *irt_nexe_desc;
389
390   struct NaClMutex          exception_mu;
391   uint32_t                  exception_handler;
392   int                       enable_exception_handling;
393 #if NACL_WINDOWS
394   enum NaClDebugExceptionHandlerState debug_exception_handler_state;
395   NaClAttachDebugExceptionHandlerFunc attach_debug_exception_handler_func;
396 #endif
397   /*
398    * enable_faulted_thread_queue is a boolean which enables handling
399    * of untrusted faults which is used by the debug stub.  When an
400    * untrusted thread faults, it is blocked until
401    * NaClAppThreadUnblockIfFaulted() is called on the thread.
402    */
403   int                       enable_faulted_thread_queue;
404   /*
405    * faulted_thread_count is the number of NaClAppThreads for which
406    * fault_signal is non-zero.
407    */
408   Atomic32                  faulted_thread_count;
409 #if NACL_WINDOWS
410   /*
411    * An event that is signaled by debug exception handler process when it fills
412    * fault_signal field with non-zero value for some NaClAppThread.
413    */
414   HANDLE                    faulted_thread_event;
415 #else
416   /*
417    * A file descriptor of a pipe which becomes available for reading in
418    * the event that fault_signal for some NaClAppThread becomes non-zero.
419    */
420   int                       faulted_thread_fd_read;
421   int                       faulted_thread_fd_write;
422 #endif
423
424   /*
425    * Cache of sysconf(_SC_NPROCESSORS_ONLN) (or equivalent) result.
426    */
427   int sc_nprocessors_onln;
428
429   const struct NaClValidatorInterface *validator;
430
431   /*
432    * Mutex for protecting futex_wait_list_head.  Lock ordering:
433    * NaClApp::mu may be claimed after futex_wait_list_mu but never
434    * before it.
435    */
436   struct NaClMutex          futex_wait_list_mu;
437   /*
438    * This is the sentinel node for a doubly linked list of
439    * NaClAppThreads.  This lists the threads that are waiting to be
440    * woken up by futex_wake().  This list must only be accessed while
441    * holding the mutex futex_wait_list_mu.
442    */
443   struct NaClListNode       futex_wait_list_head;
444 };
445
446
447
448 void  NaClAppIncrVerbosity(void);
449
450 /*
451  * Initializes a NaCl application with the default parameters
452  * and the specified syscall table.
453  *
454  * If invoked after the outer sandbox is enabled, the caller is
455  * responsible for initializing the sc_nprocessors_onln member to a
456  * sane value.
457  *
458  * nap is a pointer to the NaCl object that is being filled in.
459  *
460  * table is the NaCl syscall table. The syscall table must contain at least
461  * NACL_MAX_SYSCALLS valid entries.
462  *
463  * Caution! Syscall handlers must be extremely careful with respect to
464  * argument validation, including time-of-check vs time-of-use defense, etc.
465  */
466 int NaClAppWithSyscallTableCtor(struct NaClApp               *nap,
467                                 struct NaClSyscallTableEntry *table) NACL_WUR;
468 /*
469  * Standard Ctor for NaClApp objects.  Installs default syscall
470  * handlers.
471  *
472  * If invoked after the outer sandbox is enabled, the caller is
473  * responsible for initializing the sc_nprocessors_onln member to a
474  * sane value.
475  *
476  * nap is a pointer to the NaCl object that is being filled in.
477  */
478 int NaClAppCtor(struct NaClApp  *nap) NACL_WUR;
479
480 /*
481  * Loads a NaCl ELF file into memory in preparation for running it.
482  *
483  * gp is a pointer to a generic I/O object and should be a GioMem with
484  * a memory buffer containing the file read entirely into memory if
485  * the file system might be subject to race conditions (e.g., another
486  * thread / process might modify a downloaded NaCl ELF file while we
487  * are loading it here).
488  *
489  * nap is a pointer to the NaCl object that is being filled in.  it
490  * should be properly constructed via NaClAppCtor.
491  *
492  * return value: one of the LOAD_* values defined in
493  * nacl_error_code.h.  TODO: add some error detail string and hang
494  * that off the nap object, so that more details are available w/o
495  * incrementing verbosity (and polluting stdout).
496  *
497  * note: it may be necessary to flush the icache if the memory
498  * allocated for use had already made it into the icache from another
499  * NaCl application instance, and the icache does not detect
500  * self-modifying code / data writes and automatically invalidate the
501  * cache lines.
502  */
503 NaClErrorCode NaClAppLoadFile(struct NaClDesc *ndp,
504                               struct NaClApp *nap) NACL_WUR;
505
506 /*
507  * Just like NaClAppLoadFile, but allow control over ASLR.
508  */
509 NaClErrorCode NaClAppLoadFileAslr(struct NaClDesc *ndp,
510                                   struct NaClApp *nap,
511                                   enum NaClAslrMode aslr_mode) NACL_WUR;
512
513
514 NaClErrorCode NaClAppLoadFileDynamically(
515     struct NaClApp *nap,
516     struct NaClDesc *ndp,
517     struct NaClValidationMetadata *metadata) NACL_WUR;
518
519 void  NaClAppPrintDetails(struct NaClApp  *nap,
520                           struct Gio      *gp);
521
522 NaClErrorCode NaClLoadImage(struct Gio            *gp,
523                             struct NaClApp        *nap) NACL_WUR;
524
525 int NaClValidateCode(struct NaClApp *nap,
526                      uintptr_t      guest_addr,
527                      uint8_t        *data,
528                      size_t         size,
529                      const struct NaClValidationMetadata *metadata) NACL_WUR;
530
531 /*
532  * Validates that the code found at data_old can safely be replaced with
533  * the code found at data_new.
534  */
535 int NaClValidateCodeReplacement(struct    NaClApp *nap,
536                                 uintptr_t guest_addr,
537                                 uint8_t   *data_old,
538                                 uint8_t   *data_new,
539                                 size_t    size);
540
541 /*
542  * Copies code from data_new to data_old in a thread-safe way.
543  */
544 int NaClCopyCode(struct NaClApp *nap, uintptr_t guest_addr,
545                  uint8_t *data_old, uint8_t *data_new,
546                  size_t size);
547
548 /*
549  * Copies an instruction in a thread-safe way. Used by validators.
550  */
551 int NaClCopyInstruction(uint8_t *dst, uint8_t *src, uint8_t sz);
552
553 NaClErrorCode NaClValidateImage(struct NaClApp  *nap) NACL_WUR;
554
555
556 int NaClAddrIsValidEntryPt(struct NaClApp *nap,
557                            uintptr_t      addr);
558
559 /*
560  * Takes ownership of descriptor, i.e., when NaCl app closes, it's gone.
561  */
562 void NaClAddHostDescriptor(struct NaClApp *nap,
563                            int            host_os_desc,
564                            int            mode,
565                            int            nacl_desc);
566
567 /*
568  * Takes ownership of handle.
569  */
570 void NaClAddImcHandle(struct NaClApp  *nap,
571                       NaClHandle      h,
572                       int             nacl_desc);
573
574 /*
575  * Launch system-level service threads.  After this, access to the
576  * NaClApp object must be done in a thread-safe manner, using nap->mu
577  * etc, or access only read-only data.
578  *
579  * NB: the "secure command channel" thread should have already started
580  * (if enabled); that thread must take care to not race with the main
581  * thread that is continuing to set up the NaCl module as well.
582  */
583 int NaClAppLaunchServiceThreads(struct NaClApp *nap);
584
585 /*
586  * Report the low eight bits of |exit_status| via the reverse channel
587  * in |nap|, if one exists, to whomever is interested.  This usually
588  * involves an RPC.  Returns true if successfully reported.
589  *
590  * Also mark nap's exit_status and running member variables, announce
591  * via condvar that the nexe should be considered no longer running.
592  *
593  * Returns true (non-zero) if exit status was reported via the reverse
594  * channel, and false (0) otherwise.
595  */
596 int NaClReportExitStatus(struct NaClApp *nap, int exit_status);
597
598 /*
599  * Get the top of the initial thread's stack.  Returns a user address.
600  */
601 uintptr_t NaClGetInitialStackTop(struct NaClApp *nap);
602
603 /*
604  * Used to launch the main thread.  NB: calling thread may in the
605  * future become the main NaCl app thread, and this function will
606  * return only after the NaCl app main thread exits.  In such an
607  * alternative design, NaClWaitForMainThreadToExit will become a
608  * no-op.
609  */
610 int NaClCreateMainThread(struct NaClApp     *nap,
611                          int                argc,
612                          char               **argv,
613                          char const *const  *envp) NACL_WUR;
614
615 int NaClWaitForMainThreadToExit(struct NaClApp  *nap);
616
617 /*
618  * Used by syscall code.
619  */
620 int32_t NaClCreateAdditionalThread(struct NaClApp *nap,
621                                    uintptr_t      prog_ctr,
622                                    uintptr_t      stack_ptr,
623                                    uint32_t       user_tls1,
624                                    uint32_t       user_tls2) NACL_WUR;
625
626 void NaClLoadTrampoline(struct NaClApp *nap, enum NaClAslrMode aslr_mode);
627
628 void NaClLoadSpringboard(struct NaClApp  *nap);
629
630 static const uintptr_t kNaClBadAddress = (uintptr_t) -1;
631
632 #include "native_client/src/trusted/service_runtime/sel_ldr-inl.h"
633
634 /*
635  * Looks up a descriptor in the open-file table.  An additional
636  * reference is taken on the returned NaClDesc object (if non-NULL).
637  * The caller is responsible for invoking NaClDescUnref() on it when
638  * done.
639  */
640 struct NaClDesc *NaClAppGetDesc(struct NaClApp *nap,
641                                 int            d);
642
643 /* NaClAppSetDesc() is defined in src/public/chrome_main.h. */
644
645 int32_t NaClAppSetDescAvail(struct NaClApp   *nap,
646                             struct NaClDesc  *ndp);
647
648 /*
649  * Versions that are called while already holding the desc_mu lock
650  */
651 struct NaClDesc *NaClAppGetDescMu(struct NaClApp *nap,
652                                   int            d);
653
654 void NaClAppSetDescMu(struct NaClApp   *nap,
655                       int              d,
656                       struct NaClDesc  *ndp);
657
658 int32_t NaClAppSetDescAvailMu(struct NaClApp   *nap,
659                               struct NaClDesc  *ndp);
660
661
662 int NaClAddThread(struct NaClApp        *nap,
663                   struct NaClAppThread  *natp);
664
665 int NaClAddThreadMu(struct NaClApp        *nap,
666                     struct NaClAppThread  *natp);
667
668 void NaClRemoveThread(struct NaClApp  *nap,
669                       int             thread_num);
670
671 void NaClRemoveThreadMu(struct NaClApp  *nap,
672                         int             thread_num);
673
674 struct NaClAppThread *NaClGetThreadMu(struct NaClApp  *nap,
675                                       int             thread_num);
676
677 void NaClAppInitialDescriptorHookup(struct NaClApp  *nap);
678
679 void NaClCreateServiceSocket(struct NaClApp *nap);
680
681 void NaClSetUpBootstrapChannel(struct NaClApp  *nap,
682                                NaClHandle      inherited_desc);
683
684 void NaClSecureCommandChannel(struct NaClApp  *nap);
685
686 /*
687  * Loads the |nexe| as a NaCl app module.
688  * The |load_cb| callback is invoked before the the |nexe| is loaded to allow
689  * validation being run in parallel.
690  */
691 void NaClAppLoadModule(struct NaClApp      *self,
692                        struct NaClDesc     *nexe,
693                        void                (*load_cb)(void *instance_data,
694                                                       NaClErrorCode status),
695                        void                *instance_data);
696
697 int NaClAppRuntimeHostSetup(struct NaClApp                  *self,
698                             struct NaClRuntimeHostInterface *host_itf);
699
700 int NaClAppDescQuotaSetup(struct NaClApp                *self,
701                           struct NaClDescQuotaInterface *rev_quota);
702
703 /*
704  * Starts the NaCl app, the |start_cb| callback is invoked before the
705  * application is actually started.
706  */
707 void NaClAppStartModule(struct NaClApp  *self,
708                         void            (*start_cb)(void *instance_data,
709                                                     NaClErrorCode status),
710                         void            *instance_data);
711
712 void NaClAppShutdown(struct NaClApp     *self,
713                      int                exit_status);
714
715 NaClErrorCode NaClWaitForLoadModuleCommand(struct NaClApp *nap) NACL_WUR;
716
717 NaClErrorCode NaClWaitForLoadModuleStatus(struct NaClApp *nap) NACL_WUR;
718
719 NaClErrorCode NaClWaitForStartModuleCommand(struct NaClApp *nap) NACL_WUR;
720
721 /*
722  * NaClBlockIfCommandChannelExists is used during error exit.  If
723  * there is a secure command channel, we sent an RPC reply with the
724  * reason that the nexe was rejected.  If we exit immediately, that
725  * reply may still be in-flight and the various channel closure (esp
726  * reverse channels, if those were set up) may be detected first by
727  * the controlling process on the other end of the command channel or
728  * reverse channel.  When channel closure wins the race against the
729  * RPC reply, it would result in a crash being reported, rather than
730  * the error code carried in the RPC reply.  We want to ensure that
731  * the RPC reply to get processed.  Instead of allowing the service
732  * runtime process to exit, we block the main thread and wait for the
733  * hard-shutdown on the command channel or command channel closure.
734  *
735  * If there is no command channel, NaClBlockIfCommandChannelExists
736  * just returns immediately.
737  */
738 void NaClBlockIfCommandChannelExists(struct NaClApp *nap);
739
740 void NaClFillMemoryRegionWithHalt(void *start, size_t size);
741
742 void NaClFillTrampolineRegion(struct NaClApp *nap);
743
744 void NaClFillEndOfTextRegion(struct NaClApp *nap);
745
746 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
747
748 int NaClMakePcrelThunk(struct NaClApp *nap, enum NaClAslrMode aslr_mode);
749
750 #endif
751
752 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
753
754 int NaClMakeDispatchAddrs(struct NaClApp *nap);
755
756 void NaClPatchOneTrampolineCall(uintptr_t call_target_addr,
757                                 uintptr_t target_addr);
758
759 #endif
760
761 void NaClPatchOneTrampoline(struct NaClApp *nap,
762                             uintptr_t target_addr);
763 /*
764  * target is an absolute address in the source region.  the patch code
765  * will figure out the corresponding address in the destination region
766  * and modify as appropriate.  this makes it easier to specify, since
767  * the target is typically the address of some symbol from the source
768  * template.
769  */
770 struct NaClPatch {
771   uintptr_t           target;
772   uint64_t            value;
773 };
774
775 struct NaClPatchInfo {
776   uintptr_t           dst;
777   uintptr_t           src;
778   size_t              nbytes;
779
780   struct NaClPatch    *abs16;
781   size_t              num_abs16;
782
783   struct NaClPatch    *abs32;
784   size_t              num_abs32;
785
786   struct NaClPatch    *abs64;
787   size_t              num_abs64;
788
789 #if NACL_TARGET_SUBARCH == 32
790   uintptr_t           *rel32;
791   size_t              num_rel32;
792 #endif
793
794   uintptr_t           *rel64;
795   size_t              num_rel64;
796 };
797
798 struct NaClPatchInfo *NaClPatchInfoCtor(struct NaClPatchInfo *self);
799
800 void NaClApplyPatchToMemory(struct NaClPatchInfo *patch);
801
802 int NaClAppThreadInitArchSpecific(struct NaClAppThread *natp,
803                                   nacl_reg_t           prog_ctr,
804                                   nacl_reg_t           stack_ptr);
805
806 void NaClVmHoleWaitToStartThread(struct NaClApp *nap);
807
808 void NaClVmHoleThreadStackIsSafe(struct NaClApp *nap);
809
810 void NaClVmHoleOpeningMu(struct NaClApp *nap);
811
812 void NaClVmHoleClosingMu(struct NaClApp *nap);
813
814 /*
815  * More VM race detection.  In Windows, when we unmap or mmap over
816  * existing memory, we cannot maintain the address space reservation
817  * -- we have to unmap the original mapping with the appropriate
818  * unmapping function (VirtualFree or UnmapViewOfFile) before we can
819  * VirtualAlloc to reserve the addresss pace, leaving a timing window
820  * where another thread (possibly injected into the binary, e.g.,
821  * antivirus code) might map something else into.  We stop user-space
822  * threads when mmap/munmap occurs and detect if the temporary VM hole
823  * was filled by some other thread (and abort the process in that
824  * case), so that untrusted code cannot observe nor modify the memory
825  * that lands in the hole.  However, we still have the case where the
826  * untrusted code's threads aren't running user-space code -- a thread
827  * may have entered into a syscall handler.  We don't stop such
828  * threads, because they might be holding locks that the memory
829  * mapping functions need.  This means that, for example, a malicious
830  * application could -- assuming it could create the innocent thread
831  * race condition -- have one thread invoke the "write" NaCl syscall,
832  * enter into the host OS "write" syscall code in the NaCl syscall
833  * handler, then have another thread mmap (or munmap) the memory where
834  * the source memory region from which the content to be written
835  * resides, and as a side effect of this race, exfiltrate memory
836  * contents that NaCl modules aren't supposed to be able to access.
837  *
838  * NB: we do not try to prevent data races such as two "read" syscalls
839  * simultaneously trying to write the same memory region, or
840  * concurrent "read" and "write" syscalls racing on the same memory
841  * region..
842  */
843
844 /*
845  * Some potentially blocking I/O operation is about to start.  Syscall
846  * handlers implement DMA-style access where the host-OS syscalls
847  * directly read/write untrusted memory, so we must record the
848  * affected memory ranges as "in use" by I/O operations.
849  */
850 void NaClVmIoWillStart(struct NaClApp *nap,
851                        uint32_t addr_first_usr,
852                        uint32_t addr_last_usr);
853
854
855 /*
856  * It is a fatal error to have an invocation of NaClVmIoHasEnded whose
857  * arguments do not match those of an earlier, unmatched invocation of
858  * NaClVmIoWillStart.
859  */
860 void NaClVmIoHasEnded(struct NaClApp *nap,
861                       uint32_t addr_first_usr,
862                       uint32_t addr_last_usr);
863
864 /*
865  * Used by operations (mmap, munmap) that will open a VM hole.
866  * Invoked while holding the VM lock.  Check that no I/O is pending;
867  * abort the app if the app is racing I/O operations against VM
868  * operations.
869  */
870 void NaClVmIoPendingCheck_mu(struct NaClApp *nap,
871                              uint32_t addr_first_usr,
872                              uint32_t addr_last_usr);
873
874 void NaClGdbHook(struct NaClApp const *nap);
875
876 #if NACL_LINUX
877 void NaClHandleBootstrapArgs(int *argc_p, char ***argv_p);
878 void NaClHandleRDebug(const char *switch_value, char *argv0);
879 void NaClHandleReservedAtZero(const char *switch_value);
880 #else
881 static INLINE void NaClHandleBootstrapArgs(int *argc_p, char ***argv_p) {
882   UNREFERENCED_PARAMETER(argc_p);
883   UNREFERENCED_PARAMETER(argv_p);
884 }
885 #endif
886
887 EXTERN_C_END
888
889 #endif  /* NATIVE_CLIENT_SRC_TRUSTED_SERVICE_RUNTIME_SEL_LDR_H_ */