LCOV - code coverage report
Current view: directory - src/trusted/service_runtime - sel_ldr.h (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 4 4 100.0 %
Date: 2012-02-16 Functions: 0 0 -

       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/nacl_base.h"
      32                 : #include "native_client/src/include/portability.h"
      33                 : #include "native_client/src/include/elf.h"
      34                 : 
      35                 : #include "native_client/src/shared/platform/nacl_host_desc.h"
      36                 : #include "native_client/src/shared/platform/nacl_log.h"
      37                 : #include "native_client/src/shared/platform/nacl_threads.h"
      38                 : 
      39                 : #include "native_client/src/shared/srpc/nacl_srpc.h"
      40                 : 
      41                 : #include "native_client/src/trusted/service_runtime/dyn_array.h"
      42                 : #include "native_client/src/trusted/service_runtime/nacl_config_dangerous.h"
      43                 : #include "native_client/src/trusted/service_runtime/nacl_error_code.h"
      44                 : #include "native_client/src/trusted/service_runtime/nacl_kern_services.h"
      45                 : #include "native_client/src/trusted/service_runtime/nacl_resource.h"
      46                 : 
      47                 : #include "native_client/src/trusted/service_runtime/sel_mem.h"
      48                 : #include "native_client/src/trusted/service_runtime/sel_util.h"
      49                 : #include "native_client/src/trusted/service_runtime/sel_rt.h"
      50                 : 
      51                 : #include "native_client/src/trusted/service_runtime/name_service/name_service.h"
      52                 : 
      53                 : #include "native_client/src/trusted/validator/cpufeatures.h"
      54                 : 
      55                 : EXTERN_C_BEGIN
      56                 : 
      57                 : #define NACL_SERVICE_PORT_DESCRIPTOR    3
      58                 : #define NACL_SERVICE_ADDRESS_DESCRIPTOR 4
      59                 : 
      60                 : #define NACL_DEFAULT_STACK_MAX  (16 << 20)  /* main thread stack */
      61                 : 
      62                 : #define NACL_SANDBOX_CHROOT_FD  "SBX_D"
      63                 : 
      64                 : struct NaClAppThread;
      65                 : struct NaClDesc;  /* see native_client/src/trusted/desc/nacl_desc_base.h */
      66                 : struct NaClDynamicRegion;
      67                 : struct NaClManifestProxy;
      68                 : struct NaClReverseQuotaInterface;
      69                 : struct NaClSecureService;
      70                 : struct NaClSecureReverseService;
      71                 : struct NaClThreadInterface;  /* see sel_ldr_thread_interface.h */
      72                 : 
      73                 : struct NaClDebugCallbacks {
      74                 :   void (*thread_create_hook)(struct NaClAppThread *natp);
      75                 :   void (*thread_exit_hook)(struct NaClAppThread *natp);
      76                 :   void (*process_exit_hook)(int exit_status);
      77                 : };
      78                 : 
      79                 : enum NaClResourcePhase {
      80                 :   NACL_RESOURCE_PHASE_START,
      81                 :   NACL_RESOURCE_PHASE_REV_CHAN
      82                 : };
      83                 : 
      84                 : struct NaClApp {
      85                 :   /*
      86                 :    * public, user settable prior to app start.
      87                 :    */
      88                 :   uint8_t                   addr_bits;
      89                 :   uintptr_t                 stack_size;
      90                 :   /*
      91                 :    * stack_size is the maximum size of the (main) stack.  The stack
      92                 :    * memory is eager allocated (mapped in w/o MAP_NORESERVE) so
      93                 :    * there must be enough swap space; page table entries are not
      94                 :    * populated (no MAP_POPULATE), so actual accesses will likely
      95                 :    * incur page faults.
      96                 :    */
      97                 : 
      98                 :   /*
      99                 :    * aux_info can contain an arbitrary NUL terminated string.  It is
     100                 :    * set via the load_module RPC, and is intended to enable the
     101                 :    * browser plugin to provide information that would be useful for
     102                 :    * the debugger.
     103                 :    */
     104                 :   char                      *aux_info;
     105                 : 
     106                 :   /*
     107                 :    * Determined at load time; OS-determined.
     108                 :    * Read-only after load, so accesses do not require locking.
     109                 :    */
     110                 :   uintptr_t                 mem_start;
     111                 : 
     112                 : #if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 \
     113                 :      && NACL_BUILD_SUBARCH == 32 && __PIC__)
     114                 :   uintptr_t                 pcrel_thunk;
     115                 : #endif
     116                 : #if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 \
     117                 :      && NACL_BUILD_SUBARCH == 64)
     118                 :   uintptr_t                 dispatch_thunk;
     119                 :   uintptr_t                 get_tls_fast_path;
     120                 : #endif
     121                 : 
     122                 :   /* only used for ET_EXEC:  for CS restriction */
     123                 :   uintptr_t                 static_text_end;  /* relative to mem_start */
     124                 :   /* ro after app starts. memsz from phdr */
     125                 : 
     126                 :   /*
     127                 :    * The dynamic code area follows the static code area.  These fields
     128                 :    * are both set to static_text_end if the dynamic code area has zero
     129                 :    * size.
     130                 :    */
     131                 :   uintptr_t                 dynamic_text_start;
     132                 :   uintptr_t                 dynamic_text_end;
     133                 : 
     134                 :   /*
     135                 :    * rodata_start and data_start may be 0 if these segments are not
     136                 :    * present in the executable.
     137                 :    */
     138                 :   uintptr_t                 rodata_start;  /* initialized data, ro */
     139                 :   uintptr_t                 data_start;    /* initialized data/bss, rw */
     140                 :   /*
     141                 :    * Various region sizes must be a multiple of NACL_MAP_PAGESIZE
     142                 :    * before the NaCl app can run.  The sizes from the ELF file
     143                 :    * (p_filesz field) might not be -- that would waste space for
     144                 :    * padding -- and while we could use p_memsz to specify padding, but
     145                 :    * we will record the virtual addresses of the start of the segments
     146                 :    * and figure out the gap between the p_vaddr + p_filesz of one
     147                 :    * segment and p_vaddr of the next to determine padding.
     148                 :    */
     149                 : 
     150                 :   uintptr_t                 data_end;
     151                 :   /* see break_addr below */
     152                 : 
     153                 :   /*
     154                 :    * initial_entry_pt is the first address in untrusted code to jump
     155                 :    * to.  When using the IRT (integrated runtime), this is provided by
     156                 :    * the IRT library, and user_entry_pt is the entry point in the user
     157                 :    * executable.  Otherwise, initial_entry_pt is in the user
     158                 :    * executable and user_entry_pt is zero.
     159                 :    */
     160                 :   uintptr_t                 initial_entry_pt;
     161                 :   uintptr_t                 user_entry_pt;
     162                 : 
     163                 :   /*
     164                 :    * bundle_size is the bundle alignment boundary for validation (16
     165                 :    * or 32), so int is okay.  This value must be a power of 2.
     166                 :    */
     167                 :   int                       bundle_size;
     168                 : 
     169                 :   /* common to both ELF executables and relocatable load images */
     170                 : 
     171                 :   uintptr_t                 springboard_addr;  /* relative to mem_start */
     172                 :   /*
     173                 :    * springboard code addr for context switching into app sandbox, relative
     174                 :    * to code sandbox CS
     175                 :    */
     176                 : 
     177                 :   /*
     178                 :    * The socket at which the app should be accepting connections.  The
     179                 :    * corresponding socket address are made available by the JavaScript
     180                 :    * bridge to other NaCl modules.
     181                 :    */
     182                 :   struct NaClDesc           *service_port;
     183                 :   struct NaClDesc           *service_address;
     184                 : 
     185                 :   struct NaClMutex          mu;
     186                 :   struct NaClCondVar        cv;
     187                 : 
     188                 :   /*
     189                 :    * invariant: !(vm_hole_may_exist && threads_launching != 0).
     190                 :    * vm_hole_may_exist is set while mmap/munmap manipulates the memory
     191                 :    * map, and threads_launching is set while a thread is launching
     192                 :    * (and a trusted thread stack is being allocated).
     193                 :    *
     194                 :    * strictly speaking, vm_hole_may_exist need not be present, since
     195                 :    * the vm code ensures that 0 == threads_launching and then holds
     196                 :    * the lock for the duration of the VM operation.  it is safer this
     197                 :    * way, in case we later introduce code that might want to
     198                 :    * temporarily drop the process lock.
     199                 :    */
     200                 :   int                       vm_hole_may_exist;
     201                 :   int                       threads_launching;
     202                 : 
     203                 :   /*
     204                 :    * An array of NaCl syscall handlers. The length of the array must be
     205                 :    * at least NACL_MAX_SYSCALLS.
     206                 :    */
     207                 :   struct NaClSyscallTableEntry *syscall_table;
     208                 : 
     209                 :   /*
     210                 :    * Name service must launch after mu, cv, vm_hole_may_exit,
     211                 :    * threads_launching are initialized.
     212                 :    */
     213                 :   struct NaClNameService    *name_service;  /* default name server */
     214                 :   struct NaClDesc           *name_service_conn_cap;
     215                 : 
     216                 :   struct NaClSecureService          *secure_service;
     217                 :   struct NaClManifestProxy          *manifest_proxy;
     218                 :   struct NaClKernService            *kern_service;
     219                 : 
     220                 :   struct NaClResourceNaClApp        resources;
     221                 :   enum NaClResourcePhase            resource_phase;
     222                 : 
     223                 :   struct NaClSecureReverseClient    *reverse_client;
     224                 :   enum NaClReverseChannelInitializationState {
     225                 :     NACL_REVERSE_CHANNEL_UNINITIALIZED,
     226                 :     NACL_REVERSE_CHANNEL_INITIALIZATION_STARTED,
     227                 :     NACL_REVERSE_CHANNEL_INITIALIZED
     228                 :   }                                 reverse_channel_initialization_state;
     229                 :   struct NaClSrpcChannel            reverse_channel;
     230                 :   struct NaClReverseQuotaInterface  *reverse_quota_interface;
     231                 : 
     232                 : 
     233                 :   NaClErrorCode             module_load_status;
     234                 :   int                       module_may_start;
     235                 : 
     236                 :   /*
     237                 :    * runtime info below, thread state, etc; initialized only when app
     238                 :    * is run.  Mutex mu protects access to mem_map and other member
     239                 :    * variables while the application is running and may be
     240                 :    * multithreaded; thread, desc members have their own locks.  At
     241                 :    * other times it is assumed that only one thread is
     242                 :    * constructing/loading the NaClApp and that no mutual exclusion is
     243                 :    * needed.
     244                 :    */
     245                 : 
     246                 :   /*
     247                 :    * memory map is in user addresses.
     248                 :    */
     249                 :   struct NaClVmmap          mem_map;
     250                 : 
     251                 :   /*
     252                 :    * This is the effector interface object that is used to manipulate
     253                 :    * NaCl apps by the objects in the NaClDesc class hierarchy.  This
     254                 :    * is used by this NaClApp when making NaClDesc method calls from
     255                 :    * syscall handlers.
     256                 :    */
     257                 :   struct NaClDescEffector   *effp;
     258                 : 
     259                 :   /*
     260                 :    * may reject nexes that are incompatible w/ dynamic-text in the near future
     261                 :    */
     262                 :   int                       use_shm_for_dynamic_text;
     263                 :   struct NaClDesc           *text_shm;
     264                 :   struct NaClMutex          dynamic_load_mutex;
     265                 :   /*
     266                 :    * This records which pages in text_shm have been allocated.  When a
     267                 :    * page is allocated, it is filled with halt instructions and then
     268                 :    * made executable by untrusted code.
     269                 :    */
     270                 :   uint8_t                   *dynamic_page_bitmap;
     271                 : 
     272                 :   /*
     273                 :    * The array of dynamic_regions is maintained in sorted order
     274                 :    * Accesses must be protected by dynamic_load_mutex
     275                 :    */
     276                 :   struct NaClDynamicRegion  *dynamic_regions;
     277                 :   int                       num_dynamic_regions;
     278                 :   int                       dynamic_regions_allocated;
     279                 : 
     280                 :   /*
     281                 :    * These variables are used for caching mapped writable views of the
     282                 :    * dynamic text segment.  See CachedMapWritableText in nacl_text.c.
     283                 :    * Accesses must be protected by dynamic_load_mutex
     284                 :    */
     285                 :   uint32_t                  dynamic_mapcache_offset;
     286                 :   uint32_t                  dynamic_mapcache_size;
     287                 :   uintptr_t                 dynamic_mapcache_ret;
     288                 : 
     289                 :   /*
     290                 :    * Monotonically increasing generation number used for deletion
     291                 :    * Accesses must be protected by dynamic_load_mutex
     292                 :    */
     293                 :   int                       dynamic_delete_generation;
     294                 : 
     295                 : 
     296                 :   int                       running;
     297                 :   int                       exit_status;
     298                 : 
     299                 : 
     300                 :   NaClCPUFeatures           cpu_features;
     301                 :   int                       ignore_validator_result;
     302                 :   int                       skip_validator;
     303                 :   int                       validator_stub_out_mode;
     304                 : 
     305                 : #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
     306                 :   uint16_t                  code_seg_sel;
     307                 :   uint16_t                  data_seg_sel;
     308                 : #endif
     309                 : 
     310                 :   uintptr_t                 break_addr;   /* user addr */
     311                 :   /* data_end <= break_addr is an invariant */
     312                 : 
     313                 :   /*
     314                 :    * Thread table lock threads_mu is higher in the locking order than
     315                 :    * the thread locks, i.e., threads_mu must be acqured w/o holding
     316                 :    * any per-thread lock (natp->mu).
     317                 :    */
     318                 :   struct NaClMutex          threads_mu;
     319                 :   struct NaClCondVar        threads_cv;
     320                 :   struct DynArray           threads;   /* NaClAppThread pointers */
     321                 :   int                       num_threads;  /* number actually running */
     322                 : 
     323                 :   struct NaClMutex          desc_mu;
     324                 :   struct DynArray           desc_tbl;  /* NaClDesc pointers */
     325                 : 
     326                 :   int                       enable_debug_stub;
     327                 :   struct NaClDebugCallbacks *debug_stub_callbacks;
     328                 :   struct NaClMutex          exception_mu;
     329                 :   uint32_t                  exception_handler;
     330                 :   int                       enable_exception_handling;
     331                 : };
     332                 : 
     333                 : 
     334                 : 
     335                 : void  NaClAppIncrVerbosity(void);
     336                 : 
     337                 : /*
     338                 :  * Initializes a NaCl application with the default parameters
     339                 :  * and the specified syscall table.
     340                 :  *
     341                 :  * nap is a pointer to the NaCl object that is being filled in.
     342                 :  *
     343                 :  * table is the NaCl syscall table. The syscall table must contain at least
     344                 :  * NACL_MAX_SYSCALLS valid entries.
     345                 :  *
     346                 :  * Caution! Syscall handlers must be extremely careful with respect to
     347                 :  * argument validation, including time-of-check vs time-of-use defense, etc.
     348                 :  */
     349                 : int NaClAppWithSyscallTableCtor(struct NaClApp               *nap,
     350                 :                                 struct NaClSyscallTableEntry *table) NACL_WUR;
     351                 : 
     352                 : int   NaClAppCtor(struct NaClApp  *nap) NACL_WUR;
     353                 : 
     354                 : /*
     355                 :  * Loads a NaCl ELF file into memory in preparation for running it.
     356                 :  *
     357                 :  * gp is a pointer to a generic I/O object and should be a GioMem with
     358                 :  * a memory buffer containing the file read entirely into memory if
     359                 :  * the file system might be subject to race conditions (e.g., another
     360                 :  * thread / process might modify a downloaded NaCl ELF file while we
     361                 :  * are loading it here).
     362                 :  *
     363                 :  * nap is a pointer to the NaCl object that is being filled in.  it
     364                 :  * should be properly constructed via NaClAppCtor.
     365                 :  *
     366                 :  * return value: one of the LOAD_* values defined in
     367                 :  * nacl_error_code.h.  TODO: add some error detail string and hang
     368                 :  * that off the nap object, so that more details are available w/o
     369                 :  * incrementing verbosity (and polluting stdout).
     370                 :  *
     371                 :  * note: it may be necessary to flush the icache if the memory
     372                 :  * allocated for use had already made it into the icache from another
     373                 :  * NaCl application instance, and the icache does not detect
     374                 :  * self-modifying code / data writes and automatically invalidate the
     375                 :  * cache lines.
     376                 :  */
     377                 : NaClErrorCode NaClAppLoadFile(struct Gio      *gp,
     378                 :                               struct NaClApp  *nap) NACL_WUR;
     379                 : 
     380                 : NaClErrorCode NaClAppLoadFileDynamically(struct NaClApp *nap,
     381                 :                                          struct Gio     *gio_file) NACL_WUR;
     382                 : 
     383                 : size_t  NaClAlignPad(size_t val,
     384                 :                      size_t align);
     385                 : 
     386                 : void  NaClAppPrintDetails(struct NaClApp  *nap,
     387                 :                           struct Gio      *gp);
     388                 : 
     389                 : NaClErrorCode NaClLoadImage(struct Gio            *gp,
     390                 :                             struct NaClApp        *nap) NACL_WUR;
     391                 : 
     392                 : int NaClValidateCode(struct NaClApp *nap,
     393                 :                      uintptr_t      guest_addr,
     394                 :                      uint8_t        *data,
     395                 :                      size_t         size) NACL_WUR;
     396                 : 
     397                 : /*
     398                 :  * Validates that the code found at data_old can safely be replaced with
     399                 :  * the code found at data_new.
     400                 :  */
     401                 : int NaClValidateCodeReplacement(struct    NaClApp *nap,
     402                 :                                 uintptr_t guest_addr,
     403                 :                                 uint8_t   *data_old,
     404                 :                                 uint8_t   *data_new,
     405                 :                                 size_t    size);
     406                 : 
     407                 : /*
     408                 :  * Copies code from data_new to data_old in a thread-safe way
     409                 :  */
     410                 : int NaClCopyCode(struct NaClApp *nap, uintptr_t guest_addr,
     411                 :                  uint8_t *data_old, uint8_t *data_new,
     412                 :                  size_t size);
     413                 : 
     414                 : NaClErrorCode NaClValidateImage(struct NaClApp  *nap) NACL_WUR;
     415                 : 
     416                 : 
     417                 : int NaClAddrIsValidEntryPt(struct NaClApp *nap,
     418                 :                            uintptr_t      addr);
     419                 : 
     420                 : /*
     421                 :  * Takes ownership of descriptor, i.e., when NaCl app closes, it's gone.
     422                 :  */
     423                 : void NaClAddHostDescriptor(struct NaClApp *nap,
     424                 :                            int            host_os_desc,
     425                 :                            int            mode,
     426                 :                            int            nacl_desc);
     427                 : 
     428                 : /*
     429                 :  * Takes ownership of handle.
     430                 :  */
     431                 : void NaClAddImcHandle(struct NaClApp  *nap,
     432                 :                       NaClHandle      h,
     433                 :                       int             nacl_desc);
     434                 : 
     435                 : /*
     436                 :  * Launch system-level service threads.  After this, access to the
     437                 :  * NaClApp object must be done in a thread-safe manner, using nap->mu
     438                 :  * etc, or access only read-only data.
     439                 :  *
     440                 :  * NB: the "secure command channel" thread should have already started
     441                 :  * (if enabled); that thread must take care to not race with the main
     442                 :  * thread that is continuing to set up the NaCl module as well.
     443                 :  */
     444                 : int NaClAppLaunchServiceThreads(struct NaClApp *nap);
     445                 : 
     446                 : /*
     447                 :  * Report the low eight bits of |exit_status| via the reverse channel
     448                 :  * in |nap|, if one exists, to whomever is interested.  This usually
     449                 :  * involves an RPC.  Returns true if successfully reported.
     450                 :  *
     451                 :  * Also mark nap's exit_status and running member variables, announce
     452                 :  * via condvar that the nexe should be considered no longer running.
     453                 :  *
     454                 :  * Returns true (non-zero) if exit status was reported via the reverse
     455                 :  * channel, and false (0) otherwise.
     456                 :  */
     457                 : int NaClReportExitStatus(struct NaClApp *nap, int exit_status);
     458                 : 
     459                 : /*
     460                 :  * Used to launch the main thread.  NB: calling thread may in the
     461                 :  * future become the main NaCl app thread, and this function will
     462                 :  * return only after the NaCl app main thread exits.  In such an
     463                 :  * alternative design, NaClWaitForMainThreadToExit will become a
     464                 :  * no-op.
     465                 :  */
     466                 : int NaClCreateMainThread(struct NaClApp     *nap,
     467                 :                          int                argc,
     468                 :                          char               **argv,
     469                 :                          char const *const  *envp) NACL_WUR;
     470                 : 
     471                 : int NaClWaitForMainThreadToExit(struct NaClApp  *nap);
     472                 : 
     473                 : /*
     474                 :  * Register the integrated runtime (IRT) library file for use by
     475                 :  * NaClMainForChromium().  This takes a file descriptor, even on
     476                 :  * Windows (where file descriptors are emulated by the C runtime
     477                 :  * library).
     478                 :  */
     479                 : void NaClSetIrtFileDesc(int fd);
     480                 : 
     481                 : void NaClMainForChromium(int handle_count, const NaClHandle *handles,
     482                 :                          int debug);
     483                 : 
     484                 : /*
     485                 :  * Used by syscall code.
     486                 :  */
     487                 : int32_t NaClCreateAdditionalThread(struct NaClApp *nap,
     488                 :                                    uintptr_t      prog_ctr,
     489                 :                                    uintptr_t      stack_ptr,
     490                 :                                    uintptr_t      sys_tls,
     491                 :                                    uint32_t       user_tls2) NACL_WUR;
     492                 : 
     493                 : void NaClLoadTrampoline(struct NaClApp *nap);
     494                 : 
     495                 : void NaClLoadSpringboard(struct NaClApp  *nap);
     496                 : 
     497                 : static const uintptr_t kNaClBadAddress = (uintptr_t) -1;
     498                 : 
     499                 : #include "native_client/src/trusted/service_runtime/sel_ldr-inl.h"
     500                 : 
     501                 : /*
     502                 :  * Looks up a descriptor in the open-file table.  An additional
     503                 :  * reference is taken on the returned NaClDesc object (if non-NULL).
     504                 :  * The caller is responsible for invoking NaClDescUnref() on it when
     505                 :  * done.
     506                 :  */
     507                 : struct NaClDesc *NaClGetDesc(struct NaClApp *nap,
     508                 :                              int            d);
     509                 : 
     510                 : /*
     511                 :  * Takes ownership of ndp.
     512                 :  */
     513                 : void NaClSetDesc(struct NaClApp   *nap,
     514                 :                  int              d,
     515                 :                  struct NaClDesc  *ndp);
     516                 : 
     517                 : 
     518                 : int32_t NaClSetAvail(struct NaClApp   *nap,
     519                 :                      struct NaClDesc  *ndp);
     520                 : 
     521                 : /*
     522                 :  * Versions that are called while already holding the desc_mu lock
     523                 :  */
     524                 : struct NaClDesc *NaClGetDescMu(struct NaClApp *nap,
     525                 :                                int            d);
     526                 : 
     527                 : void NaClSetDescMu(struct NaClApp   *nap,
     528                 :                    int              d,
     529                 :                    struct NaClDesc  *ndp);
     530                 : 
     531                 : int32_t NaClSetAvailMu(struct NaClApp   *nap,
     532                 :                        struct NaClDesc  *ndp);
     533                 : 
     534                 : 
     535                 : int NaClAddThread(struct NaClApp        *nap,
     536                 :                   struct NaClAppThread  *natp);
     537                 : 
     538                 : int NaClAddThreadMu(struct NaClApp        *nap,
     539                 :                     struct NaClAppThread  *natp);
     540                 : 
     541                 : void NaClRemoveThread(struct NaClApp  *nap,
     542                 :                       int             thread_num);
     543                 : 
     544                 : void NaClRemoveThreadMu(struct NaClApp  *nap,
     545                 :                         int             thread_num);
     546                 : 
     547                 : struct NaClAppThread *NaClGetThreadMu(struct NaClApp  *nap,
     548                 :                                       int             thread_num);
     549                 : 
     550                 : void NaClAppInitialDescriptorHookup(struct NaClApp  *nap);
     551                 : 
     552                 : void NaClAppVmmapUpdate(struct NaClApp    *nap,
     553                 :                         uintptr_t         page_num,
     554                 :                         size_t            npages,
     555                 :                         int               prot,
     556                 :                         struct NaClMemObj *nmop,
     557                 :                         int               remove);
     558                 : 
     559                 : uintptr_t NaClAppVmmapFindSpace(struct NaClApp  *nap,
     560                 :                                 int             num_pages);
     561                 : 
     562                 : uintptr_t NaClAppVmmapFindMapSpace(struct NaClApp *nap,
     563                 :                                    int            num_pages);
     564                 : 
     565                 : void NaClCreateServiceSocket(struct NaClApp *nap);
     566                 : 
     567                 : void NaClSendServiceAddressTo(struct NaClApp  *nap,
     568                 :                               int             desc);
     569                 : 
     570                 : void NaClSecureCommandChannel(struct NaClApp  *nap);
     571                 : 
     572                 : int NaClSecureReverseClientInsertHandler(
     573                 :     struct NaClSecureReverseClient  *self,
     574                 :     void                            (*handler)(
     575                 :         void                                   *handler_state,
     576                 :         struct NaClThreadInterface             *thread_if,
     577                 :         struct NaClDesc                        *new_conn),
     578                 :     void                            *handler_state) NACL_WUR;
     579                 : 
     580                 : NaClErrorCode NaClWaitForLoadModuleStatus(struct NaClApp *nap) NACL_WUR;
     581                 : 
     582                 : NaClErrorCode NaClWaitForStartModuleCommand(struct NaClApp *nap) NACL_WUR;
     583                 : 
     584                 : /*
     585                 :  * NaClBlockIfCommandChannelExists is used during error exit.  If
     586                 :  * there is a secure command channel, we sent an RPC reply with the
     587                 :  * reason that the nexe was rejected.  If we exit immediately, that
     588                 :  * reply may still be in-flight and the various channel closure (esp
     589                 :  * reverse channels, if those were set up) may be detected first by
     590                 :  * the controlling process on the other end of the command channel or
     591                 :  * reverse channel.  When channel closure wins the race against the
     592                 :  * RPC reply, it would result in a crash being reported, rather than
     593                 :  * the error code carried in the RPC reply.  We want to ensure that
     594                 :  * the RPC reply to get processed.  Instead of allowing the service
     595                 :  * runtime process to exit, we block the main thread and wait for the
     596                 :  * hard-shutdown on the command channel or command channel closure.
     597                 :  *
     598                 :  * If there is no command channel, NaClBlockIfCommandChannelExists
     599                 :  * just returns immediately.
     600                 :  */
     601                 : void NaClBlockIfCommandChannelExists(struct NaClApp *nap);
     602                 : 
     603                 : void NaClFillMemoryRegionWithHalt(void *start, size_t size);
     604                 : 
     605                 : void NaClFillTrampolineRegion(struct NaClApp *nap);
     606                 : 
     607                 : void NaClFillEndOfTextRegion(struct NaClApp *nap);
     608                 : 
     609                 : #if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 \
     610                 :      && NACL_BUILD_SUBARCH == 32 && __PIC__)
     611                 : 
     612                 : int NaClMakePcrelThunk(struct NaClApp *nap);
     613                 : 
     614                 : #endif
     615                 : 
     616                 : #if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 \
     617                 :      && NACL_BUILD_SUBARCH == 64)
     618                 : 
     619                 : int NaClMakeDispatchThunk(struct NaClApp *nap);
     620                 : void NaClPatchOneTrampolineCall(uintptr_t call_target_addr,
     621                 :                                 uintptr_t target_addr);
     622                 : 
     623                 : #endif
     624                 : 
     625                 : #if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 \
     626                 :      && NACL_BUILD_SUBARCH == 32)
     627                 : 
     628                 : void NaClPatchDebuggerInfo(struct NaClApp *nap);
     629                 : 
     630                 : #endif
     631                 : 
     632                 : void NaClPatchOneTrampoline(struct NaClApp *nap,
     633                 :                             uintptr_t target_addr);
     634                 : /*
     635                 :  * target is an absolute address in the source region.  the patch code
     636                 :  * will figure out the corresponding address in the destination region
     637                 :  * and modify as appropriate.  this makes it easier to specify, since
     638                 :  * the target is typically the address of some symbol from the source
     639                 :  * template.
     640                 :  */
     641                 : struct NaClPatch {
     642                 :   uintptr_t           target;
     643                 :   uint64_t            value;
     644                 : };
     645                 : 
     646                 : struct NaClPatchInfo {
     647                 :   uintptr_t           dst;
     648                 :   uintptr_t           src;
     649                 :   size_t              nbytes;
     650                 : 
     651                 :   struct NaClPatch    *abs16;
     652                 :   size_t              num_abs16;
     653                 : 
     654                 :   struct NaClPatch    *abs32;
     655                 :   size_t              num_abs32;
     656                 : 
     657                 :   struct NaClPatch    *abs64;
     658                 :   size_t              num_abs64;
     659                 : 
     660                 : #if NACL_TARGET_SUBARCH == 32
     661                 :   uintptr_t           *rel32;
     662                 :   size_t              num_rel32;
     663                 : #endif
     664                 : 
     665                 :   uintptr_t           *rel64;
     666                 :   size_t              num_rel64;
     667                 : };
     668                 : 
     669                 : struct NaClPatchInfo *NaClPatchInfoCtor(struct NaClPatchInfo *self);
     670                 : 
     671                 : void NaClApplyPatchToMemory(struct NaClPatchInfo *patch);
     672                 : 
     673                 : int NaClThreadContextCtor(struct NaClThreadContext  *ntcp,
     674                 :                           struct NaClApp            *nap,
     675                 :                           nacl_reg_t                prog_ctr,
     676                 :                           nacl_reg_t                stack_ptr,
     677                 :                           uint32_t                  tls_info);
     678                 : 
     679                 : void NaClThreadContextDtor(struct NaClThreadContext *ntcp);
     680                 : 
     681                 : void NaClVmHoleWaitToStartThread(struct NaClApp *nap);
     682                 : 
     683                 : void NaClVmHoleThreadStackIsSafe(struct NaClApp *nap);
     684                 : 
     685                 : void NaClGdbHook(struct NaClApp const *nap);
     686                 : 
     687                 : #if NACL_WINDOWS
     688                 : 
     689                 : void NaClUntrustedThreadsSuspend(struct NaClApp *nap);
     690                 : void NaClUntrustedThreadsResume(struct NaClApp *nap);
     691                 : 
     692                 : #else
     693                 : 
     694                 : /*
     695                 :  * Suspending untrusted threads is only needed for preventing mmap
     696                 :  * races on Windows, so these are no-ops on other platforms.
     697                 :  */
     698                 : 
     699               7 : static INLINE void NaClUntrustedThreadsSuspend(struct NaClApp *nap) {
     700                 :   UNREFERENCED_PARAMETER(nap);
     701               7 : }
     702                 : 
     703               7 : static INLINE void NaClUntrustedThreadsResume(struct NaClApp *nap) {
     704                 :   UNREFERENCED_PARAMETER(nap);
     705               7 : }
     706                 : 
     707                 : #endif
     708                 : 
     709                 : #if NACL_LINUX
     710                 : void handle_r_debug(const char *switch_value, char *argv0);
     711                 : #endif
     712                 : 
     713                 : EXTERN_C_END
     714                 : 
     715                 : #endif  /* NATIVE_CLIENT_SRC_TRUSTED_SERVICE_RUNTIME_SEL_LDR_H_ */

Generated by: LCOV version 1.7