LCOV - code coverage report
Current view: directory - src/trusted/service_runtime - env_cleanser.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 83 75 90.4 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2011 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 <stdio.h>
       8                 : #include <stdlib.h>
       9                 : #include <string.h>
      10                 : 
      11                 : #include "native_client/src/include/portability.h"
      12                 : #include "native_client/src/include/nacl_macros.h"
      13                 : 
      14                 : #include "native_client/src/trusted/service_runtime/env_cleanser.h"
      15                 : #include "native_client/src/trusted/service_runtime/env_cleanser_test.h"
      16                 : 
      17                 : /*
      18                 :  * Everything that starts with this prefix is allowed (but the prefix is
      19                 :  * stripped away).
      20                 : */
      21                 : #define NACL_ENV_PREFIX "NACLENV_"
      22                 : #define NACL_ENV_PREFIX_LENGTH 8
      23                 : 
      24             257 : void NaClEnvCleanserCtor(struct NaClEnvCleanser *self, int with_whitelist) {
      25             257 :   self->with_whitelist = with_whitelist;
      26             257 :   self->cleansed_environ = (char const **) NULL;
      27             257 : }
      28                 : 
      29                 : /*
      30                 :  * Environment variables names are from IEEE Std 1003.1-2001, with
      31                 :  * additional ones from locale(7) from glibc / linux.  The entries
      32                 :  * must be sorted, in ASCII order, for the bsearch to run correctly.
      33                 :  */
      34                 : /* static -- not static for testing */
      35                 : char const *const kNaClEnvWhitelist[] = {
      36                 :   "LANG",
      37                 :   "LC_ADDRESS",
      38                 :   "LC_ALL",
      39                 :   "LC_COLLATE",
      40                 :   "LC_CTYPE",
      41                 :   "LC_IDENTIFICATION",
      42                 :   "LC_MEASUREMENT",
      43                 :   "LC_MESSAGES",
      44                 :   "LC_MONETARY",
      45                 :   "LC_NAME",
      46                 :   "LC_NUMERIC",
      47                 :   "LC_PAPER",
      48                 :   "LC_TELEPHONE",
      49                 :   "LC_TIME",
      50                 :   "NACLVERBOSITY",
      51                 :   "NACL_NPAPI_DEBUG",       /* src/shared/npruntime/naclnp_util.cc */
      52                 :   "NACL_PLUGIN_DEBUG",      /* src/trusted/plugin/srpc/utility.cc */
      53                 :   "NACL_PPAPI_PROXY_DEBUG", /* src/shared/ppapi_proxy/utility.cc */
      54                 :   "NACL_SRPC_DEBUG",        /* src/shared/srpc/utility.c */
      55                 :   "NACL_SRPC_STANDALONE",   /* src/shared/srpc/nacl_srpc.c */
      56                 :   NULL,
      57                 : };
      58                 : 
      59                 : /* left arg is key, right arg is table entry */
      60            1594 : static int EnvCmp(void const *vleft, void const *vright) {
      61            1594 :   char const *left = *(char const *const *) vleft;
      62            1594 :   char const *right = *(char const *const *) vright;
      63            1594 :   char cleft, cright;
      64                 : 
      65            5525 :   while ((cleft = *left) == (cright = *right)
      66                 :          && '\0' != cleft
      67                 :          && '\0' != cright) {
      68             772 :     ++left;
      69             772 :     ++right;
      70             772 :   }
      71            1610 :   if ('=' == cleft && '\0' == cright) {
      72              16 :     return 0;
      73                 :   }
      74            1578 :   return (0xff & cleft) - (0xff & cright);
      75            1594 : }
      76                 : 
      77           18970 : int NaClEnvIsPassThroughVar(char const *env_entry) {
      78           18970 :   return strlen(env_entry) > NACL_ENV_PREFIX_LENGTH &&
      79           18448 :       0 == strncmp(env_entry, NACL_ENV_PREFIX,
      80                 :           NACL_ENV_PREFIX_LENGTH);
      81           18970 : }
      82                 : 
      83             353 : int NaClEnvInWhitelist(char const *env_entry) {
      84             353 :   return NULL != bsearch((void const *) &env_entry,
      85                 :                          (void const *) kNaClEnvWhitelist,
      86                 :                          NACL_ARRAY_SIZE(kNaClEnvWhitelist) - 1,  /* NULL */
      87                 :                          sizeof kNaClEnvWhitelist[0],
      88                 :                          EnvCmp);
      89                 : }
      90                 : 
      91                 : /* PRE: sizeof(char *) is a power of 2 */
      92                 : 
      93                 : /*
      94                 :  * Initializes the object with a filtered environment.
      95                 :  *
      96                 :  * May return false on errors, e.g., out-of-memory.
      97                 :  */
      98             257 : int NaClEnvCleanserInit(struct NaClEnvCleanser *self, char const *const *envp,
      99             257 :     char const * const *extra_env) {
     100             257 :   char const *const *p;
     101             257 :   size_t num_env = 0;
     102             257 :   size_t ptr_bytes = 0;
     103             257 :   const size_t kMaxSize = ~(size_t) 0;
     104             257 :   const size_t ptr_size_mult_overflow_mask = ~(kMaxSize / sizeof *envp);
     105             257 :   char const **ptr_tbl;
     106             257 :   size_t env;
     107                 : 
     108                 :   /*
     109                 :    * let n be a size_t.  if n & ptr_size_mult_overflow_mask is set,
     110                 :    * then n*sizeof(void *) will have an arithmetic overflow.
     111                 :    */
     112                 : 
     113             514 :   if (NULL == envp || NULL == *envp) {
     114               0 :     self->cleansed_environ = NULL;
     115               0 :     return 1;
     116                 :   }
     117           19490 :   for (p = envp; NULL != *p; ++p) {
     118            9650 :     if (!(self->with_whitelist && NaClEnvInWhitelist(*p)) &&
     119            9482 :         !NaClEnvIsPassThroughVar(*p)) {
     120            9478 :       continue;
     121                 :     }
     122              10 :     if (num_env == kMaxSize) {
     123                 :       /* would overflow */
     124               0 :       return 0;
     125                 :     }
     126              10 :     ++num_env;
     127              10 :   }
     128                 : 
     129             257 :   if (extra_env) {
     130             526 :     for (p = extra_env; NULL != *p; ++p) {
     131              12 :       if (num_env == kMaxSize) {
     132                 :         /* would overflow */
     133               0 :         return 0;
     134                 :       }
     135              12 :       ++num_env;
     136              12 :     }
     137             251 :   }
     138                 : 
     139                 :   /* pointer table -- NULL pointer terminated */
     140             257 :   if (0 != ((1 + num_env) & ptr_size_mult_overflow_mask)) {
     141               0 :     return 0;
     142                 :   }
     143             257 :   ptr_bytes = (1 + num_env) * sizeof(*envp);
     144                 : 
     145             257 :   ptr_tbl = (char const **) malloc(ptr_bytes);
     146             257 :   if (NULL == ptr_tbl) {
     147               0 :     return 0;
     148                 :   }
     149                 : 
     150                 :   /* this assumes no other thread is tweaking envp */
     151           19490 :   for (env = 0, p = envp; NULL != *p; ++p) {
     152            9488 :     if (NaClEnvIsPassThroughVar(*p)) {
     153               4 :       ptr_tbl[env] = *p + NACL_ENV_PREFIX_LENGTH;
     154            9648 :     } else if (self->with_whitelist && NaClEnvInWhitelist(*p)) {
     155               6 :       ptr_tbl[env] = *p;
     156               6 :     } else {
     157            9478 :       continue;
     158                 :     }
     159              10 :     ++env;
     160              10 :   }
     161             257 :   if (extra_env) {
     162             526 :     for (p = extra_env; NULL != *p; ++p) {
     163              12 :       ptr_tbl[env] = *p;
     164              12 :       ++env;
     165              12 :     }
     166             251 :   }
     167             257 :   if (num_env != env) {
     168               0 :     free((void *) ptr_tbl);
     169               0 :     return 0;
     170                 :   }
     171             257 :   ptr_tbl[env] = NULL;
     172             257 :   self->cleansed_environ = ptr_tbl;
     173                 : 
     174             257 :   return 1;
     175             257 : }
     176                 : 
     177             257 : char const *const *NaClEnvCleanserEnvironment(struct NaClEnvCleanser *self) {
     178             257 :   return (char const *const *) self->cleansed_environ;
     179                 : }
     180                 : 
     181             257 : void NaClEnvCleanserDtor(struct NaClEnvCleanser *self) {
     182             257 :   free((void *) self->cleansed_environ);
     183             257 :   self->cleansed_environ = NULL;
     184             257 : }

Generated by: LCOV version 1.7