LCOV - code coverage report
Current view: directory - src/trusted/service_runtime - env_cleanser.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 76 60 78.9 %
Date: 2014-09-25 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               1 : void NaClEnvCleanserCtor(struct NaClEnvCleanser *self, int with_whitelist) {
      25               1 :   self->with_whitelist = with_whitelist;
      26               1 :   self->cleansed_environ = (char const **) NULL;
      27               1 : }
      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_PLUGIN_DEBUG",      /* src/trusted/plugin/srpc/utility.cc */
      52                 :   "NACL_SRPC_DEBUG",        /* src/shared/srpc/utility.c */
      53                 :   NULL,
      54                 : };
      55                 : 
      56                 : /* left arg is key, right arg is table entry */
      57               1 : static int EnvCmp(void const *vleft, void const *vright) {
      58               1 :   char const *left = *(char const *const *) vleft;
      59               1 :   char const *right = *(char const *const *) vright;
      60                 :   char cleft, cright;
      61                 : 
      62                 :   while ((cleft = *left) == (cright = *right)
      63                 :          && '\0' != cleft
      64               1 :          && '\0' != cright) {
      65               1 :     ++left;
      66               1 :     ++right;
      67               1 :   }
      68               1 :   if ('=' == cleft && '\0' == cright) {
      69               1 :     return 0;
      70                 :   }
      71               1 :   return (0xff & cleft) - (0xff & cright);
      72               1 : }
      73                 : 
      74               1 : int NaClEnvIsPassThroughVar(char const *env_entry) {
      75                 :   return strlen(env_entry) > NACL_ENV_PREFIX_LENGTH &&
      76                 :       0 == strncmp(env_entry, NACL_ENV_PREFIX,
      77               1 :           NACL_ENV_PREFIX_LENGTH);
      78               1 : }
      79                 : 
      80               1 : int NaClEnvInWhitelist(char const *env_entry) {
      81                 :   return NULL != bsearch((void const *) &env_entry,
      82                 :                          (void const *) kNaClEnvWhitelist,
      83                 :                          NACL_ARRAY_SIZE(kNaClEnvWhitelist) - 1,  /* NULL */
      84                 :                          sizeof kNaClEnvWhitelist[0],
      85               1 :                          EnvCmp);
      86               1 : }
      87                 : 
      88                 : /* PRE: sizeof(char *) is a power of 2 */
      89                 : 
      90                 : /*
      91                 :  * Initializes the object with a filtered environment.
      92                 :  *
      93                 :  * May return false on errors, e.g., out-of-memory.
      94                 :  */
      95                 : int NaClEnvCleanserInit(struct NaClEnvCleanser *self, char const *const *envp,
      96               1 :     char const * const *extra_env) {
      97                 :   char const *const *p;
      98               1 :   size_t num_env = 0;
      99               1 :   size_t ptr_bytes = 0;
     100               1 :   const size_t kMaxSize = ~(size_t) 0;
     101               1 :   const size_t ptr_size_mult_overflow_mask = ~(kMaxSize / sizeof *envp);
     102                 :   char const **ptr_tbl;
     103                 :   size_t env;
     104                 : 
     105                 :   /*
     106                 :    * let n be a size_t.  if n & ptr_size_mult_overflow_mask is set,
     107                 :    * then n*sizeof(void *) will have an arithmetic overflow.
     108                 :    */
     109                 : 
     110               1 :   if (NULL == envp || NULL == *envp) {
     111               0 :     self->cleansed_environ = NULL;
     112               0 :     return 1;
     113                 :   }
     114               1 :   for (p = envp; NULL != *p; ++p) {
     115                 :     if (!(self->with_whitelist && NaClEnvInWhitelist(*p)) &&
     116               1 :         !NaClEnvIsPassThroughVar(*p)) {
     117               1 :       continue;
     118                 :     }
     119               1 :     if (num_env == kMaxSize) {
     120                 :       /* would overflow */
     121               0 :       return 0;
     122                 :     }
     123               1 :     ++num_env;
     124               1 :   }
     125                 : 
     126               1 :   if (extra_env) {
     127               0 :     for (p = extra_env; NULL != *p; ++p) {
     128               0 :       if (num_env == kMaxSize) {
     129                 :         /* would overflow */
     130               0 :         return 0;
     131                 :       }
     132               0 :       ++num_env;
     133               0 :     }
     134                 :   }
     135                 : 
     136                 :   /* pointer table -- NULL pointer terminated */
     137               1 :   if (0 != ((1 + num_env) & ptr_size_mult_overflow_mask)) {
     138               0 :     return 0;
     139                 :   }
     140               1 :   ptr_bytes = (1 + num_env) * sizeof(*envp);
     141                 : 
     142               1 :   ptr_tbl = (char const **) malloc(ptr_bytes);
     143               1 :   if (NULL == ptr_tbl) {
     144               0 :     return 0;
     145                 :   }
     146                 : 
     147                 :   /* this assumes no other thread is tweaking envp */
     148               1 :   for (env = 0, p = envp; NULL != *p; ++p) {
     149               1 :     if (NaClEnvIsPassThroughVar(*p)) {
     150               1 :       ptr_tbl[env] = *p + NACL_ENV_PREFIX_LENGTH;
     151               1 :     } else if (self->with_whitelist && NaClEnvInWhitelist(*p)) {
     152               1 :       ptr_tbl[env] = *p;
     153               1 :     } else {
     154               1 :       continue;
     155                 :     }
     156               1 :     ++env;
     157               1 :   }
     158               1 :   if (extra_env) {
     159               0 :     for (p = extra_env; NULL != *p; ++p) {
     160               0 :       ptr_tbl[env] = *p;
     161               0 :       ++env;
     162               0 :     }
     163                 :   }
     164               1 :   if (num_env != env) {
     165               0 :     free((void *) ptr_tbl);
     166               0 :     return 0;
     167                 :   }
     168               1 :   ptr_tbl[env] = NULL;
     169               1 :   self->cleansed_environ = ptr_tbl;
     170                 : 
     171               1 :   return 1;
     172               1 : }
     173                 : 
     174               1 : char const *const *NaClEnvCleanserEnvironment(struct NaClEnvCleanser *self) {
     175               1 :   return (char const *const *) self->cleansed_environ;
     176               1 : }
     177                 : 
     178               1 : void NaClEnvCleanserDtor(struct NaClEnvCleanser *self) {
     179               1 :   free((void *) self->cleansed_environ);
     180               1 :   self->cleansed_environ = NULL;
     181               1 : }

Generated by: LCOV version 1.7