LCOV - code coverage report
Current view: directory - src/trusted/service_runtime - sel_ldr-inl.h (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 44 39 88.6 %
Date: 2014-07-02 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                 :  *
       9                 :  * DO NOT INCLUDE EXCEPT FROM sel_ldr.h
      10                 :  *
      11                 :  ******************************************************************************/
      12                 : 
      13                 : /*
      14                 :  * Routines to translate addresses between user and "system" or
      15                 :  * service runtime addresses.  the *Addr* versions will return
      16                 :  * kNaClBadAddress if the user address is outside of the user address
      17                 :  * space, e.g., if the input addresses for *UserToSys* is outside of
      18                 :  * (1<<nap->addr_bits), and correspondingly for *SysToUser* if the
      19                 :  * input system address does not correspond to a user address.
      20                 :  * Generally, the *Addr* versions are used when the addresses come
      21                 :  * from untrusted usre code, and kNaClBadAddress would translate to an
      22                 :  * EINVAL return from a syscall.  The *Range code ensures that the
      23                 :  * entire address range is in the user address space.
      24                 :  *
      25                 :  * Note that just because an address is within the address space, it
      26                 :  * doesn't mean that it is safe to acceess the memory: the page may be
      27                 :  * protected against access.
      28                 :  *
      29                 :  * The non-*Addr* versions abort the program rather than return an
      30                 :  * error indication.
      31                 :  */
      32                 : 
      33                 : /*
      34                 :  * address translation routines.  after a NaClApp is started, the
      35                 :  * member variables accessed by these routines are read-only, so no
      36                 :  * locking is needed to use these functions, as long as the NaClApp
      37                 :  * structure doesn't get destructed/deallocated.
      38                 :  *
      39                 :  * the first is used internally when a NULL pointer is okay, typically
      40                 :  * for address manipulation.
      41                 :  *
      42                 :  * the next two are for syscalls to do address translation, e.g., for
      43                 :  * system calls; -1 indicates an error, so the syscall can return
      44                 :  * EINVAL or EFAULT or whatever is appropriate.
      45                 :  *
      46                 :  * the latter two interfaces are for use everywhere else in the loader
      47                 :  * / service runtime and will log a fatal error and abort the process
      48                 :  * when an error is detected.  (0 is not a good error indicator, since
      49                 :  * 0 is a valid user address.)
      50                 :  */
      51                 : 
      52                 : #include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h"
      53                 : 
      54              39 : static INLINE uintptr_t NaClUserToSysAddrNullOkay(struct NaClApp  *nap,
      55                 :                                                   uintptr_t       uaddr) {
      56              39 :   if (((uintptr_t) 1U << nap->addr_bits <= uaddr)) {
      57               0 :     return kNaClBadAddress;
      58                 :   }
      59              39 :   return uaddr + nap->mem_start;
      60                 : }
      61                 : 
      62           30216 : static INLINE uintptr_t NaClUserToSysAddr(struct NaClApp  *nap,
      63                 :                                           uintptr_t       uaddr) {
      64           30216 :   if (0 == uaddr || ((uintptr_t) 1U << nap->addr_bits) <= uaddr) {
      65              14 :     return kNaClBadAddress;
      66                 :   }
      67           30202 :   return uaddr + nap->mem_start;
      68                 : }
      69                 : 
      70                 : static INLINE int NaClIsUserAddr(struct NaClApp  *nap,
      71                 :                                  uintptr_t       sysaddr) {
      72                 :   /*
      73                 :    * Note that NaClIsUserAddr() is used in the Windows debug exception
      74                 :    * handler so must remain safe to use on a copy of NaClApp.
      75                 :    */
      76                 :   return nap->mem_start <= sysaddr &&
      77                 :          sysaddr < nap->mem_start + ((uintptr_t) 1U << nap->addr_bits);
      78                 : }
      79                 : 
      80         2382876 : static INLINE uintptr_t NaClUserToSysAddrRange(struct NaClApp  *nap,
      81                 :                                                uintptr_t       uaddr,
      82                 :                                                size_t          count) {
      83                 :   uintptr_t end_addr;
      84                 : 
      85         2382876 :   if (0 == uaddr) {
      86               3 :     return kNaClBadAddress;
      87                 :   }
      88         2382873 :   end_addr = uaddr + count;
      89         2382873 :   if (end_addr < uaddr) {
      90                 :     /* unsigned wraparound */
      91               5 :     return kNaClBadAddress;
      92                 :   }
      93         2382868 :   if (((uintptr_t) 1U << nap->addr_bits) < end_addr) {
      94               4 :     return kNaClBadAddress;
      95                 :   }
      96         2382864 :   return uaddr + nap->mem_start;
      97                 : }
      98                 : 
      99         2767934 : static INLINE uintptr_t NaClUserToSys(struct NaClApp  *nap,
     100                 :                                       uintptr_t       uaddr) {
     101         2767934 :   if (0 == uaddr || ((uintptr_t) 1U << nap->addr_bits) <= uaddr) {
     102               0 :     NaClLog(LOG_FATAL,
     103                 :             "NaClUserToSys: uaddr 0x%08" NACL_PRIxPTR ", "
     104                 :             "addr space %" NACL_PRId8 " bits\n",
     105               0 :             uaddr, nap->addr_bits);
     106                 :   }
     107         2767946 :   return uaddr + nap->mem_start;
     108                 : }
     109                 : 
     110          127034 : static INLINE uintptr_t NaClSysToUser(struct NaClApp  *nap,
     111                 :                                       uintptr_t       sysaddr) {
     112          254068 :   if (sysaddr < nap->mem_start ||
     113          127034 :       nap->mem_start + ((uintptr_t) 1U << nap->addr_bits) <= sysaddr) {
     114               0 :     NaClLog(LOG_FATAL,
     115                 :             ("NaClSysToUser: sysaddr 0x%08" NACL_PRIxPTR ","
     116                 :              " mem_start 0x%08" NACL_PRIxPTR ","
     117                 :              " addr space %" NACL_PRId8 " bits\n"),
     118               0 :             sysaddr, nap->mem_start, nap->addr_bits);
     119                 :   }
     120          127034 :   return sysaddr - nap->mem_start;
     121                 : }
     122                 : 
     123                 : #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
     124                 : /*
     125                 :  * For x86-64 sandboxing, %rsp and %rbp are system addresses already.
     126                 :  */
     127                 : static INLINE uintptr_t NaClUserToSysStackAddr(struct NaClApp *nap,
     128                 :                                                uintptr_t      stackaddr) {
     129                 :   UNREFERENCED_PARAMETER(nap);
     130                 :   return stackaddr;
     131                 : }
     132                 : 
     133                 : static INLINE uintptr_t NaClSysToUserStackAddr(struct NaClApp *nap,
     134                 :                                                uintptr_t      stackaddr) {
     135                 :   UNREFERENCED_PARAMETER(nap);
     136                 :   return stackaddr;
     137                 : }
     138                 : 
     139                 : #else
     140                 : 
     141         2716830 : static INLINE uintptr_t NaClUserToSysStackAddr(struct NaClApp *nap,
     142                 :                                                uintptr_t      stackaddr) {
     143         2716830 :   return NaClUserToSys(nap, stackaddr);
     144                 : }
     145                 : 
     146           29700 : static INLINE uintptr_t NaClSysToUserStackAddr(struct NaClApp *nap,
     147                 :                                                uintptr_t      stackaddr) {
     148           29700 :   return NaClSysToUser(nap, stackaddr);
     149                 : }
     150                 : 
     151                 : #endif
     152                 : 
     153                 : /*
     154                 :  * Normalize a user address space address.  This function is really a
     155                 :  * no-op for 32-bit sandboxes, but for x86-64 where rsp contains a
     156                 :  * true 64-bit address, we must discard the high 32 bits to make the
     157                 :  * stack address a proper user-space address.  After normalization,
     158                 :  * the address can be used with NaClUserToSys etc.
     159                 :  */
     160         2716851 : static INLINE uint32_t NaClRawUserStackAddrNormalize(uintptr_t  stack_addr) {
     161         2716851 :   return (uint32_t) stack_addr;
     162                 : }
     163                 : 
     164             585 : static INLINE uintptr_t NaClEndOfStaticText(struct NaClApp *nap) {
     165             585 :   return nap->static_text_end;
     166                 : }
     167                 : 
     168         2729901 : static INLINE uintptr_t NaClSandboxCodeAddr(struct NaClApp *nap,
     169                 :                                             uintptr_t addr) {
     170                 : #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
     171                 :   /*
     172                 :    * If misaligned, round up to the following bundle boundary.
     173                 :    * With the original nacl-gcc toolchain, a return address is
     174                 :    * always on a bundle boundary, so this is always a no-op and
     175                 :    * the ABI specification was that a misaligned return address
     176                 :    * has undefined results.  With the next-generation gcc
     177                 :    * toolchain, a return address on the stack may be mid-bundle
     178                 :    * and the ABI specification is that the real address to use is
     179                 :    * found by rounding up to the following bundle.
     180                 :    */
     181         2729901 :   addr += (uintptr_t) nap->bundle_size - 1;
     182         2729901 :   addr &= ~((uintptr_t) nap->bundle_size - 1);
     183                 : # if NACL_BUILD_SUBARCH == 32
     184         2729901 :   return addr;
     185                 : # elif NACL_BUILD_SUBARCH == 64
     186                 :   return nap->mem_start + (uint32_t) addr;
     187                 : # else
     188                 : #  error "What kind of x86 are we on anyway?!?"
     189                 : # endif
     190                 : #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
     191                 :   UNREFERENCED_PARAMETER(nap);
     192                 :   addr &= ~NACL_CONTROL_FLOW_MASK;
     193                 :   return addr;
     194                 : #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
     195                 :   UNREFERENCED_PARAMETER(nap);
     196                 :   return addr & NACL_CONTROL_FLOW_MASK;
     197                 : #else
     198                 : # error "What architecture are we on?!?"
     199                 : #endif
     200                 : }
     201                 : 
     202           29300 : static INLINE int NaClIsValidJumpTarget(struct NaClApp *nap,
     203                 :                                         uintptr_t addr) {
     204           29300 :   if (0 != (addr & (((uintptr_t) nap->bundle_size) - 1))) {
     205               3 :     return 0;
     206                 :   }
     207           29297 :   return addr < nap->dynamic_text_end;
     208                 : }

Generated by: LCOV version 1.7