LCOV - code coverage report
Current view: directory - src/trusted/service_runtime - nacl_resource.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 136 84 61.8 %
Date: 2014-06-18 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                 : #include <string.h>
       8                 : 
       9                 : #include "native_client/src/trusted/service_runtime/nacl_resource.h"
      10                 : 
      11                 : #include "native_client/src/include/nacl_base.h"
      12                 : #include "native_client/src/include/nacl_macros.h"
      13                 : #include "native_client/src/shared/platform/nacl_check.h"
      14                 : #include "native_client/src/shared/platform/nacl_log.h"
      15                 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
      16                 : #include "native_client/src/trusted/desc/nacl_desc_io.h"
      17                 : #include "native_client/src/trusted/desc/nacl_desc_null.h"
      18                 : #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
      19                 : #include "native_client/src/trusted/service_runtime/nacl_desc_postmessage.h"
      20                 : #include "native_client/src/trusted/service_runtime/sel_ldr.h"
      21                 : 
      22               3 : struct NaClDesc *NaClResourceOpen(struct NaClResource *self,
      23               3 :                                   char const          *resource_locator,
      24               3 :                                   int                 nacl_flags,
      25               3 :                                   int                 mode) {
      26               3 :   size_t  ix;
      27               3 :   size_t  default_ix = ~(size_t) 0;  /* greater than self->num_schemes */
      28               3 :   size_t  prefix_len;
      29               3 :   int     allow_debug = 0;
      30                 : 
      31               3 :   NaClLog(4, "NaClResourceOpen(*,\"%s\",0x%x,0%o)\n",
      32                 :           resource_locator, nacl_flags, mode);
      33               3 :   prefix_len = strlen(NACL_RESOURCE_DEBUG_WARNING);
      34               3 :   if (strncmp(resource_locator, NACL_RESOURCE_DEBUG_WARNING,
      35                 :               prefix_len) == 0) {
      36               0 :     allow_debug = 1;
      37               0 :     resource_locator += prefix_len;
      38               0 :   }
      39                 : 
      40              18 :   for (ix = 0; ix < self->num_schemes; ++ix) {
      41               6 :     if (self->schemes[ix].default_scheme) {
      42               3 :       default_ix = ix;
      43               3 :     }
      44               6 :     prefix_len = strlen(self->schemes[ix].scheme_prefix);
      45               6 :     NaClLog(4, " prefix \"%s\"\n", self->schemes[ix].scheme_prefix);
      46               6 :     if (0 == strncmp(self->schemes[ix].scheme_prefix, resource_locator,
      47                 :                      prefix_len)) {
      48               0 :       char const *rest = resource_locator + prefix_len;
      49               0 :       NaClLog(4, " prefix match at %"NACL_PRIuS", rest \"%s\".\n", ix, rest);
      50               0 :       return (*self->schemes[ix].Open)(self, rest,
      51                 :                                        nacl_flags, mode, allow_debug);
      52                 :     }
      53               6 :   }
      54               3 :   if (default_ix < self->num_schemes) {
      55               3 :     NaClLog(4, " trying default scheme %"NACL_PRIuS".\n", default_ix);
      56               3 :     return (*self->schemes[default_ix].Open)(self, resource_locator,
      57                 :                                              nacl_flags, mode, allow_debug);
      58                 :   }
      59               0 :   NaClLog(4, " no match, and no default scheme to try.");
      60               0 :   return NULL;
      61               3 : }
      62                 : 
      63             296 : int NaClResourceCtor(struct NaClResource              *self,
      64             296 :                      struct NaClResourceSchemes const *scheme_tbl,
      65             296 :                      size_t                           num_schemes) {
      66             296 :   self->schemes = scheme_tbl;
      67             296 :   self->num_schemes = num_schemes;
      68             296 :   return 1;
      69                 : }
      70                 : 
      71                 : /* --------------------------------------------------------------------------
      72                 :  *
      73                 :  * Subclass of NaClResource
      74                 :  *
      75                 :  * --------------------------------------------------------------------------
      76                 :  */
      77                 : 
      78             296 : int NaClResourceNaClAppCtor(struct NaClResourceNaClApp        *self,
      79             296 :                             struct NaClResourceSchemes const  *scheme_tbl,
      80             296 :                             size_t                            num_schemes,
      81             296 :                             struct NaClApp                    *nap) {
      82             296 :   NaClLog(4,
      83                 :           ("NaClResourceNaClAppCtor, scheme_tbl 0x%"NACL_PRIxPTR","
      84                 :            " size %"NACL_PRIuS".\n"),
      85                 :           (uintptr_t) scheme_tbl, num_schemes);
      86             296 :   if (!NaClResourceCtor(&self->base, scheme_tbl, num_schemes)) {
      87               0 :     return 0;
      88                 :   }
      89             296 :   self->nap = nap;
      90             296 :   return 1;
      91             296 : }
      92                 : 
      93                 : static struct NaClDesc *NaClResourceNullFactory(void) {
      94               2 :   struct NaClDescNull *null_desc = NULL;
      95                 : 
      96               1 :   null_desc = malloc(sizeof *null_desc);
      97               1 :   if (NULL == null_desc) {
      98               0 :     return NULL;
      99                 :   }
     100               1 :   if (!NaClDescNullCtor(null_desc)) {
     101               0 :     free(null_desc);
     102               0 :     null_desc = NULL;
     103               0 :   }
     104               1 :   return (struct NaClDesc *) null_desc;
     105               1 : }
     106                 : 
     107               2 : static struct NaClDesc *NaClResourceFileFactory(char const *resource_locator,
     108               2 :                                                 int nacl_flags,
     109               2 :                                                 int mode) {
     110               2 :   struct NaClHostDesc         *hd = NULL;
     111               2 :   struct NaClDescIoDesc       *did = NULL;
     112               2 :   struct NaClDesc             *rv = NULL;
     113                 : 
     114               2 :   hd = malloc(sizeof *hd);
     115               2 :   did = malloc(sizeof *did);
     116               4 :   if (NULL == hd || NULL == did) {
     117               0 :     goto done;
     118                 :   }
     119               2 :   NaClLog(4,
     120                 :           ("NaClResourceFileFactory: invoking NaClHostDescOpen on"
     121                 :            " %s, flags 0x%x, mode 0%o\n"),
     122                 :           resource_locator, nacl_flags, mode);
     123               2 :   if (0 != NaClHostDescOpen(hd, resource_locator, nacl_flags, mode)) {
     124               0 :     NaClLog(LOG_INFO,
     125                 :             "NaClResourceFileFactory: NaClHostDescOpen failed\n");
     126               0 :     goto done;
     127                 :   }
     128               2 :   if (!NaClDescIoDescCtor(did, hd)) {
     129               0 :     NaClLog(LOG_INFO,
     130                 :             "NaClResourceFileFactory: NaClDescIoDescCtor failed\n");
     131               0 :     if (0 != NaClHostDescClose(hd)) {
     132               0 :       NaClLog(LOG_FATAL, "NaClResourceFileFactory: NaClHostDescClose failed\n");
     133               0 :     }
     134               0 :     goto done;
     135                 :   }
     136               2 :   hd = NULL;  /* ownership passed into did */
     137               2 :   rv = (struct NaClDesc *) did;  /* success */
     138               2 :   did = NULL;
     139                 :  done:
     140               2 :   free(hd);
     141               2 :   free(did);
     142               2 :   return rv;
     143                 : }
     144                 : 
     145                 : static struct NaClDesc *NaClResourceNaClAppFileOpen(
     146               3 :     struct NaClResource *vself,
     147               3 :     char const *resource_locator,
     148               3 :     int nacl_flags,
     149               3 :     int mode,
     150               3 :     int allow_debug) {
     151               3 :   struct NaClResourceNaClApp *self = (struct NaClResourceNaClApp *) vself;
     152               3 :   struct NaClDesc *rv = NULL;
     153                 : 
     154                 :   /*
     155                 :    * Initialization order requires that file opens occur only early,
     156                 :    * in NACl_RESOURCE_PHASE_START, because otherwise (in the OSX case)
     157                 :    * the sandbox gets enabled after the reverse channel is set up, and
     158                 :    * the ability to open files go away.
     159                 :    */
     160               6 :   UNREFERENCED_PARAMETER(allow_debug);
     161               3 :   if (self->nap->resource_phase != NACL_RESOURCE_PHASE_START) {
     162               0 :     return NULL;
     163                 :   }
     164               3 :   if (0 == strcmp(resource_locator, NACL_RESOURCE_FILE_DEV_NULL)) {
     165               1 :     rv = NaClResourceNullFactory();
     166               1 :     if (NULL == rv) {
     167               0 :       NaClLog(LOG_ERROR, "Could not create Null device. Redirect failed.\n");
     168               0 :     }
     169               1 :   } else {
     170               2 :     rv = NaClResourceFileFactory(resource_locator, nacl_flags, mode);
     171               2 :     if (NULL == rv) {
     172               0 :       NaClLog(LOG_ERROR, "Could not open file \"%s\". Redirect failed.\n",
     173                 :               resource_locator);
     174               0 :     }
     175                 :   }
     176               3 :   NaClLog(4, "NaClResourceNaClAppFileOpen returning 0x%"NACL_PRIxPTR"\n",
     177                 :           (uintptr_t) rv);
     178               3 :   return rv;
     179               3 : }
     180                 : 
     181                 : /*
     182                 :  * We don't bother to make it a singleton postmessage device.  Thread
     183                 :  * safety is handled when the device object gets the lock to use the
     184                 :  * reverse channel.
     185                 :  */
     186                 : static struct NaClDesc *NaClResourceNaClAppDevOpen(
     187               0 :     struct NaClResource *vself,
     188               0 :     char const          *resource_locator,
     189               0 :     int                 nacl_flags,
     190               0 :     int                 mode,
     191               0 :     int                 allow_debug) {
     192               0 :   struct NaClResourceNaClApp  *self = (struct NaClResourceNaClApp *) vself;
     193               0 :   struct NaClDescPostMessage  *ndpm = NULL;
     194                 : 
     195               0 :   if (self->nap->resource_phase != NACL_RESOURCE_PHASE_RUNTIME_HOST
     196                 :       || !allow_debug) {
     197               0 :     return NULL;
     198                 :   }
     199                 : 
     200               0 :   if (0 == strcmp(resource_locator, NACL_RESOURCE_DEV_POSTMESSAGE_LOCATOR)) {
     201                 :     /* disallow O_RDONLY or O_RDWR */
     202               0 :     if ((NACL_ABI_O_ACCMODE & nacl_flags) != NACL_ABI_O_WRONLY) {
     203               0 :       return NULL;
     204                 :     }
     205                 :     /* allow O_CREAT, O_APPEND, and O_TRUNC */
     206               0 :     UNREFERENCED_PARAMETER(mode);  /* ignored; O_CREAT doesn't create. */
     207                 : 
     208               0 :     ndpm = malloc(sizeof *ndpm);
     209               0 :     if (NULL != ndpm) {
     210               0 :       if (!NaClDescPostMessageCtor(ndpm, self->nap->runtime_host_interface)) {
     211               0 :         free(ndpm);
     212               0 :         ndpm = NULL;
     213               0 :       }
     214               0 :     }
     215               0 :     if (NULL == ndpm) {
     216               0 :       NaClLog(LOG_ERROR,
     217                 :               "NaClResourceNaClAppDevOpen(%s) failed\n",
     218                 :               resource_locator);
     219               0 :     }
     220               0 :   }
     221               0 :   return (struct NaClDesc *) ndpm;
     222               0 : }
     223                 : 
     224             296 : int NaClResourceNaClAppInit(struct NaClResourceNaClApp  *rp,
     225             296 :                             struct NaClApp              *nap) {
     226                 :   static struct NaClResourceSchemes const schemes[] = {
     227                 :     {
     228                 :       NACL_RESOURCE_FILE_PREFIX,
     229                 :       1,  /* default scheme */
     230                 :       NaClResourceNaClAppFileOpen,
     231                 :     }, {
     232                 :       NACL_RESOURCE_DEV_PREFIX,
     233                 :       0,  /* not default scheme */
     234                 :       NaClResourceNaClAppDevOpen,
     235                 :     },
     236                 :   };
     237                 : 
     238             296 :   NaClLog(4, "NaClResourceNaClAppInit -- Ctor with default schemes\n");
     239             296 :   return NaClResourceNaClAppCtor(rp, schemes, NACL_ARRAY_SIZE(schemes), nap);
     240                 : }

Generated by: LCOV version 1.7