Browse Source

src: make copies of startup environment variables

Mutations of the environment can invalidate pointers to environment
variables, so make `secure_getenv()` copy them out instead of returning
pointers.

PR-URL: https://github.com/nodejs/node/pull/11051
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
v6.x
Ben Noordhuis 8 years ago
committed by Myles Borins
parent
commit
f2e97f89f0
No known key found for this signature in database GPG Key ID: 933B01F40B5CA946
  1. 43
      src/node.cc
  2. 6
      src/node_i18n.cc
  3. 3
      src/node_i18n.h
  4. 2
      src/node_internals.h

43
src/node.cc

@ -167,7 +167,7 @@ static node_module* modlist_addon;
#if defined(NODE_HAVE_I18N_SUPPORT) #if defined(NODE_HAVE_I18N_SUPPORT)
// Path to ICU data (for i18n / Intl) // Path to ICU data (for i18n / Intl)
static const char* icu_data_dir = nullptr; static std::string icu_data_dir; // NOLINT(runtime/string)
#endif #endif
// used by C++ modules as well // used by C++ modules as well
@ -945,12 +945,21 @@ Local<Value> UVException(Isolate* isolate,
// Look up environment variable unless running as setuid root. // Look up environment variable unless running as setuid root.
inline const char* secure_getenv(const char* key) { inline bool SafeGetenv(const char* key, std::string* text) {
#ifndef _WIN32 #ifndef _WIN32
if (getuid() != geteuid() || getgid() != getegid()) // TODO(bnoordhuis) Should perhaps also check whether getauxval(AT_SECURE)
return nullptr; // is non-zero on Linux.
if (getuid() != geteuid() || getgid() != getegid()) {
text->clear();
return false;
}
#endif #endif
return getenv(key); if (const char* value = getenv(key)) {
*text = value;
return true;
}
text->clear();
return false;
} }
@ -3136,11 +3145,11 @@ void SetupProcessObject(Environment* env,
"icu", "icu",
OneByteString(env->isolate(), U_ICU_VERSION)); OneByteString(env->isolate(), U_ICU_VERSION));
if (icu_data_dir != nullptr) { if (!icu_data_dir.empty()) {
// Did the user attempt (via env var or parameter) to set an ICU path? // Did the user attempt (via env var or parameter) to set an ICU path?
READONLY_PROPERTY(process, READONLY_PROPERTY(process,
"icu_data_dir", "icu_data_dir",
OneByteString(env->isolate(), icu_data_dir)); OneByteString(env->isolate(), icu_data_dir.c_str()));
} }
#endif #endif
@ -3855,7 +3864,7 @@ static void ParseArgs(int* argc,
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
#if defined(NODE_HAVE_I18N_SUPPORT) #if defined(NODE_HAVE_I18N_SUPPORT)
} else if (strncmp(arg, "--icu-data-dir=", 15) == 0) { } else if (strncmp(arg, "--icu-data-dir=", 15) == 0) {
icu_data_dir = arg + 15; icu_data_dir.assign(arg + 15);
#endif #endif
} else if (strcmp(arg, "--expose-internals") == 0 || } else if (strcmp(arg, "--expose-internals") == 0 ||
strcmp(arg, "--expose_internals") == 0) { strcmp(arg, "--expose_internals") == 0) {
@ -4372,12 +4381,11 @@ void Init(int* argc,
#endif #endif
#if defined(NODE_HAVE_I18N_SUPPORT) #if defined(NODE_HAVE_I18N_SUPPORT)
if (icu_data_dir == nullptr) { // If the parameter isn't given, use the env variable.
// if the parameter isn't given, use the env variable. if (icu_data_dir.empty())
icu_data_dir = secure_getenv("NODE_ICU_DATA"); SafeGetenv("NODE_ICU_DATA", &icu_data_dir);
}
// Initialize ICU. // Initialize ICU.
// If icu_data_dir is nullptr here, it will load the 'minimal' data. // If icu_data_dir is empty here, it will load the 'minimal' data.
if (!i18n::InitializeICUDirectory(icu_data_dir)) { if (!i18n::InitializeICUDirectory(icu_data_dir)) {
FatalError(nullptr, "Could not initialize ICU " FatalError(nullptr, "Could not initialize ICU "
"(check NODE_ICU_DATA or --icu-data-dir parameters)"); "(check NODE_ICU_DATA or --icu-data-dir parameters)");
@ -4718,8 +4726,11 @@ int Start(int argc, char** argv) {
Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv); Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
#if HAVE_OPENSSL #if HAVE_OPENSSL
if (const char* extra = secure_getenv("NODE_EXTRA_CA_CERTS")) {
crypto::UseExtraCaCerts(extra); std::string extra_ca_certs;
if (SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs))
crypto::UseExtraCaCerts(extra_ca_certs);
}
#ifdef NODE_FIPS_MODE #ifdef NODE_FIPS_MODE
// In the case of FIPS builds we should make sure // In the case of FIPS builds we should make sure
// the random source is properly initialized first. // the random source is properly initialized first.
@ -4728,7 +4739,7 @@ int Start(int argc, char** argv) {
// V8 on Windows doesn't have a good source of entropy. Seed it from // V8 on Windows doesn't have a good source of entropy. Seed it from
// OpenSSL's pool. // OpenSSL's pool.
V8::SetEntropySource(crypto::EntropySource); V8::SetEntropySource(crypto::EntropySource);
#endif #endif // HAVE_OPENSSL
v8_platform.Initialize(v8_thread_pool_size); v8_platform.Initialize(v8_thread_pool_size);
V8::Initialize(); V8::Initialize();

6
src/node_i18n.cc

@ -62,10 +62,10 @@ bool flag_icu_data_dir = false;
namespace i18n { namespace i18n {
bool InitializeICUDirectory(const char* icu_data_path) { bool InitializeICUDirectory(const std::string& path) {
if (icu_data_path != nullptr) { if (!path.empty()) {
flag_icu_data_dir = true; flag_icu_data_dir = true;
u_setDataDirectory(icu_data_path); u_setDataDirectory(path.c_str());
return true; // no error return true; // no error
} else { } else {
UErrorCode status = U_ZERO_ERROR; UErrorCode status = U_ZERO_ERROR;

3
src/node_i18n.h

@ -4,6 +4,7 @@
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#include "node.h" #include "node.h"
#include <string>
#if defined(NODE_HAVE_I18N_SUPPORT) #if defined(NODE_HAVE_I18N_SUPPORT)
@ -13,7 +14,7 @@ extern bool flag_icu_data_dir;
namespace i18n { namespace i18n {
bool InitializeICUDirectory(const char* icu_data_path); bool InitializeICUDirectory(const std::string& path);
} // namespace i18n } // namespace i18n
} // namespace node } // namespace node

2
src/node_internals.h

@ -12,6 +12,8 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string>
struct sockaddr; struct sockaddr;
// Variation on NODE_DEFINE_CONSTANT that sets a String value. // Variation on NODE_DEFINE_CONSTANT that sets a String value.

Loading…
Cancel
Save