tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

env_interposer.cpp (2164B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include <pthread.h>
      6 #include <string.h>
      7 #include <unistd.h>
      8 
      9 #include "InterposerHelper.h"
     10 
     11 // The interposers in this file cover all the functions used to access the
     12 // environment (getenv(), putenv(), setenv(), unsetenv() and clearenv()). They
     13 // all use the mutex below for synchronization to prevent races that caused
     14 // startup crashes, see bug 1752703.
     15 static pthread_mutex_t gEnvLock = PTHREAD_MUTEX_INITIALIZER;
     16 
     17 static char* internal_getenv(const char* aName) {
     18  if (environ == nullptr || aName[0] == '\0') {
     19    return nullptr;
     20  }
     21 
     22  size_t len = strlen(aName);
     23  for (char** env_ptr = environ; *env_ptr != nullptr; ++env_ptr) {
     24    if ((aName[0] == (*env_ptr)[0]) && (strncmp(aName, *env_ptr, len) == 0) &&
     25        ((*env_ptr)[len] == '=')) {
     26      return *env_ptr + len + 1;
     27    }
     28  }
     29 
     30  return nullptr;
     31 }
     32 
     33 extern "C" {
     34 
     35 MFBT_API char* getenv(const char* name) {
     36  pthread_mutex_lock(&gEnvLock);
     37  char* result = internal_getenv(name);
     38  pthread_mutex_unlock(&gEnvLock);
     39 
     40  return result;
     41 }
     42 
     43 MFBT_API int putenv(char* string) {
     44  static const auto real_putenv = GET_REAL_SYMBOL(putenv);
     45 
     46  pthread_mutex_lock(&gEnvLock);
     47  int result = real_putenv(string);
     48  pthread_mutex_unlock(&gEnvLock);
     49  return result;
     50 }
     51 
     52 MFBT_API int setenv(const char* name, const char* value, int replace) {
     53  static const auto real_setenv = GET_REAL_SYMBOL(setenv);
     54 
     55  pthread_mutex_lock(&gEnvLock);
     56  int result = real_setenv(name, value, replace);
     57  pthread_mutex_unlock(&gEnvLock);
     58  return result;
     59 }
     60 
     61 MFBT_API int unsetenv(const char* name) {
     62  static const auto real_unsetenv = GET_REAL_SYMBOL(unsetenv);
     63 
     64  pthread_mutex_lock(&gEnvLock);
     65  int result = real_unsetenv(name);
     66  pthread_mutex_unlock(&gEnvLock);
     67  return result;
     68 }
     69 
     70 MFBT_API int clearenv(void) {
     71  static const auto real_clearenv = GET_REAL_SYMBOL(clearenv);
     72 
     73  pthread_mutex_lock(&gEnvLock);
     74  int result = real_clearenv();
     75  pthread_mutex_unlock(&gEnvLock);
     76  return result;
     77 }
     78 
     79 }  // extern "C"