Commit c0f57472 authored by Gabriele Svelto's avatar Gabriele Svelto
Browse files

Bug 1752703 - Add interposers for functions manipulating the environment to...

Bug 1752703 - Add interposers for functions manipulating the environment to prevent crashes r=glandium

This add interposers for getenv(), putenv(), setenv(), unsetenv() and
clearenv(). All interposers use a single lock for synchronization while
internally using the libc-provided functions. This is done to prevent races
that typically happen in Firefox code when multiple threads call getenv()
while others are changing variables using setenv() and putenv().

Differential Revision: https://phabricator.services.mozilla.com/D164471
parent 63bfefbb
Loading
Loading
Loading
Loading
+62 −0
Original line number Original line Diff line number Diff line
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <pthread.h>

#include "InterposerHelper.h"

// The interposers in this file cover all the functions used to access the
// environment (getenv(), putenv(), setenv(), unsetenv() and clearenv()). They
// all use the mutex below for synchronization to prevent races that caused
// startup crashes, see bug 1752703.
static pthread_mutex_t gEnvLock = PTHREAD_MUTEX_INITIALIZER;

extern "C" {

MFBT_API char* getenv(const char* name) {
  static const auto real_getenv = GET_REAL_SYMBOL(getenv);

  pthread_mutex_lock(&gEnvLock);
  char* result = real_getenv(name);
  pthread_mutex_unlock(&gEnvLock);
  return result;
}

MFBT_API int putenv(char* string) {
  static const auto real_putenv = GET_REAL_SYMBOL(putenv);

  pthread_mutex_lock(&gEnvLock);
  int result = real_putenv(string);
  pthread_mutex_unlock(&gEnvLock);
  return result;
}

MFBT_API int setenv(const char* name, const char* value, int replace) {
  static const auto real_setenv = GET_REAL_SYMBOL(setenv);

  pthread_mutex_lock(&gEnvLock);
  int result = real_setenv(name, value, replace);
  pthread_mutex_unlock(&gEnvLock);
  return result;
}

MFBT_API int unsetenv(const char* name) {
  static const auto real_unsetenv = GET_REAL_SYMBOL(unsetenv);

  pthread_mutex_lock(&gEnvLock);
  int result = real_unsetenv(name);
  pthread_mutex_unlock(&gEnvLock);
  return result;
}

MFBT_API int clearenv(void) {
  static const auto real_clearenv = GET_REAL_SYMBOL(clearenv);

  pthread_mutex_lock(&gEnvLock);
  int result = real_clearenv();
  pthread_mutex_unlock(&gEnvLock);
  return result;
}

}  // extern "C"
+4 −0
Original line number Original line Diff line number Diff line
@@ -7,6 +7,10 @@ Library("interposers")


DEFINES["IMPL_MFBT"] = True
DEFINES["IMPL_MFBT"] = True


UNIFIED_SOURCES += [
    "env_interposer.cpp",
]

if CONFIG["MOZ_CRASHREPORTER"]:
if CONFIG["MOZ_CRASHREPORTER"]:
    UNIFIED_SOURCES += [
    UNIFIED_SOURCES += [
        "pthread_create_interposer.cpp",
        "pthread_create_interposer.cpp",