mirror of
https://github.com/nodejs/node.git
synced 2025-05-15 12:45:25 +00:00
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>
This commit is contained in:
parent
62f513a9c8
commit
a8734af442
56
src/node.cc
56
src/node.cc
@ -156,7 +156,7 @@ static const char* trace_enabled_categories = nullptr;
|
|||||||
|
|
||||||
#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
|
||||||
@ -189,7 +189,7 @@ bool trace_warnings = false;
|
|||||||
bool config_preserve_symlinks = false;
|
bool config_preserve_symlinks = false;
|
||||||
|
|
||||||
// Set in node.cc by ParseArgs when --redirect-warnings= is used.
|
// Set in node.cc by ParseArgs when --redirect-warnings= is used.
|
||||||
const char* config_warning_file;
|
std::string config_warning_file; // NOLINT(runtime/string)
|
||||||
|
|
||||||
bool v8_initialized = false;
|
bool v8_initialized = false;
|
||||||
|
|
||||||
@ -924,12 +924,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3089,11 +3098,11 @@ void SetupProcessObject(Environment* env,
|
|||||||
#if defined(NODE_HAVE_I18N_SUPPORT) && defined(U_ICU_VERSION)
|
#if defined(NODE_HAVE_I18N_SUPPORT) && defined(U_ICU_VERSION)
|
||||||
// ICU-related versions are now handled on the js side, see bootstrap_node.js
|
// ICU-related versions are now handled on the js side, see bootstrap_node.js
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
@ -3741,7 +3750,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) {
|
||||||
@ -4228,13 +4237,14 @@ void Init(int* argc,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Allow for environment set preserving symlinks.
|
// Allow for environment set preserving symlinks.
|
||||||
if (auto preserve_symlinks = secure_getenv("NODE_PRESERVE_SYMLINKS")) {
|
{
|
||||||
config_preserve_symlinks = (*preserve_symlinks == '1');
|
std::string text;
|
||||||
|
config_preserve_symlinks =
|
||||||
|
SafeGetenv("NODE_PRESERVE_SYMLINKS", &text) && text[0] == '1';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto redirect_warnings = secure_getenv("NODE_REDIRECT_WARNINGS")) {
|
if (config_warning_file.empty())
|
||||||
config_warning_file = redirect_warnings;
|
SafeGetenv("NODE_REDIRECT_WARNINGS", &config_warning_file);
|
||||||
}
|
|
||||||
|
|
||||||
// Parse a few arguments which are specific to Node.
|
// Parse a few arguments which are specific to Node.
|
||||||
int v8_argc;
|
int v8_argc;
|
||||||
@ -4262,12 +4272,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)");
|
||||||
@ -4532,8 +4541,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.
|
||||||
@ -4542,7 +4554,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);
|
||||||
// Enable tracing when argv has --trace-events-enabled.
|
// Enable tracing when argv has --trace-events-enabled.
|
||||||
|
@ -46,11 +46,12 @@ void InitConfig(Local<Object> target,
|
|||||||
if (config_preserve_symlinks)
|
if (config_preserve_symlinks)
|
||||||
READONLY_BOOLEAN_PROPERTY("preserveSymlinks");
|
READONLY_BOOLEAN_PROPERTY("preserveSymlinks");
|
||||||
|
|
||||||
if (config_warning_file != nullptr) {
|
if (!config_warning_file.empty()) {
|
||||||
Local<String> name = OneByteString(env->isolate(), "warningFile");
|
Local<String> name = OneByteString(env->isolate(), "warningFile");
|
||||||
Local<String> value = String::NewFromUtf8(env->isolate(),
|
Local<String> value = String::NewFromUtf8(env->isolate(),
|
||||||
config_warning_file,
|
config_warning_file.data(),
|
||||||
v8::NewStringType::kNormal)
|
v8::NewStringType::kNormal,
|
||||||
|
config_warning_file.size())
|
||||||
.ToLocalChecked();
|
.ToLocalChecked();
|
||||||
target->DefineOwnProperty(env->context(), name, value).FromJust();
|
target->DefineOwnProperty(env->context(), name, value).FromJust();
|
||||||
}
|
}
|
||||||
|
@ -404,12 +404,8 @@ static void GetVersion(const FunctionCallbackInfo<Value>& args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
u_setDataDirectory(icu_data_path);
|
|
||||||
return true; // no error
|
|
||||||
} else {
|
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
#ifdef NODE_HAVE_SMALL_ICU
|
#ifdef NODE_HAVE_SMALL_ICU
|
||||||
// install the 'small' data.
|
// install the 'small' data.
|
||||||
@ -418,6 +414,10 @@ bool InitializeICUDirectory(const char* icu_data_path) {
|
|||||||
// no small data, so nothing to do.
|
// no small data, so nothing to do.
|
||||||
#endif // !NODE_HAVE_SMALL_ICU
|
#endif // !NODE_HAVE_SMALL_ICU
|
||||||
return (status == U_ZERO_ERROR);
|
return (status == U_ZERO_ERROR);
|
||||||
|
} else {
|
||||||
|
flag_icu_data_dir = true;
|
||||||
|
u_setDataDirectory(path.c_str());
|
||||||
|
return true; // No error.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
int32_t ToASCII(MaybeStackBuffer<char>* buf,
|
int32_t ToASCII(MaybeStackBuffer<char>* buf,
|
||||||
const char* input,
|
const char* input,
|
||||||
|
@ -13,6 +13,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.
|
||||||
@ -45,7 +47,7 @@ extern bool config_preserve_symlinks;
|
|||||||
// Set in node.cc by ParseArgs when --redirect-warnings= is used.
|
// Set in node.cc by ParseArgs when --redirect-warnings= is used.
|
||||||
// Used to redirect warning output to a file rather than sending
|
// Used to redirect warning output to a file rather than sending
|
||||||
// it to stderr.
|
// it to stderr.
|
||||||
extern const char* config_warning_file;
|
extern std::string config_warning_file; // NOLINT(runtime/string)
|
||||||
|
|
||||||
// Tells whether it is safe to call v8::Isolate::GetCurrent().
|
// Tells whether it is safe to call v8::Isolate::GetCurrent().
|
||||||
extern bool v8_initialized;
|
extern bool v8_initialized;
|
||||||
|
Loading…
Reference in New Issue
Block a user