Skip to content

Commit dcdebc3

Browse files
bnoordhuissam-github
authored andcommitted
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: nodejs#11051 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Sam Roberts <[email protected]>
1 parent fe99edd commit dcdebc3

File tree

4 files changed

+41
-25
lines changed

4 files changed

+41
-25
lines changed

src/node.cc

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ static node_module* modlist_addon;
154154

155155
#if defined(NODE_HAVE_I18N_SUPPORT)
156156
// Path to ICU data (for i18n / Intl)
157-
static const char* icu_data_dir = nullptr;
157+
static std::string icu_data_dir; // NOLINT(runtime/string)
158158
#endif
159159

160160
// used by C++ modules as well
@@ -901,12 +901,21 @@ Local<Value> UVException(Isolate* isolate,
901901

902902

903903
// Look up environment variable unless running as setuid root.
904-
inline const char* secure_getenv(const char* key) {
904+
inline bool SafeGetenv(const char* key, std::string* text) {
905905
#ifndef _WIN32
906-
if (getuid() != geteuid() || getgid() != getegid())
907-
return nullptr;
906+
// TODO(bnoordhuis) Should perhaps also check whether getauxval(AT_SECURE)
907+
// is non-zero on Linux.
908+
if (getuid() != geteuid() || getgid() != getegid()) {
909+
text->clear();
910+
return false;
911+
}
908912
#endif
909-
return getenv(key);
913+
if (const char* value = getenv(key)) {
914+
*text = value;
915+
return true;
916+
}
917+
text->clear();
918+
return false;
910919
}
911920

912921

@@ -3063,11 +3072,11 @@ void SetupProcessObject(Environment* env,
30633072
#if defined(NODE_HAVE_I18N_SUPPORT) && defined(U_ICU_VERSION)
30643073
// ICU-related versions are now handled on the js side, see bootstrap_node.js
30653074

3066-
if (icu_data_dir != nullptr) {
3075+
if (!icu_data_dir.empty()) {
30673076
// Did the user attempt (via env var or parameter) to set an ICU path?
30683077
READONLY_PROPERTY(process,
30693078
"icu_data_dir",
3070-
OneByteString(env->isolate(), icu_data_dir));
3079+
OneByteString(env->isolate(), icu_data_dir.c_str()));
30713080
}
30723081
#endif
30733082

@@ -3696,7 +3705,7 @@ static void ParseArgs(int* argc,
36963705
#endif /* HAVE_OPENSSL */
36973706
#if defined(NODE_HAVE_I18N_SUPPORT)
36983707
} else if (strncmp(arg, "--icu-data-dir=", 15) == 0) {
3699-
icu_data_dir = arg + 15;
3708+
icu_data_dir.assign(arg, 15);
37003709
#endif
37013710
} else if (strcmp(arg, "--expose-internals") == 0 ||
37023711
strcmp(arg, "--expose_internals") == 0) {
@@ -4183,8 +4192,10 @@ void Init(int* argc,
41834192
#endif
41844193

41854194
// Allow for environment set preserving symlinks.
4186-
if (auto preserve_symlinks = secure_getenv("NODE_PRESERVE_SYMLINKS")) {
4187-
config_preserve_symlinks = (*preserve_symlinks == '1');
4195+
{
4196+
std::string text;
4197+
config_preserve_symlinks =
4198+
SafeGetenv("NODE_PRESERVE_SYMLINKS", &text) && text[0] == '1';
41884199
}
41894200

41904201
// Parse a few arguments which are specific to Node.
@@ -4213,12 +4224,11 @@ void Init(int* argc,
42134224
#endif
42144225

42154226
#if defined(NODE_HAVE_I18N_SUPPORT)
4216-
if (icu_data_dir == nullptr) {
4217-
// if the parameter isn't given, use the env variable.
4218-
icu_data_dir = secure_getenv("NODE_ICU_DATA");
4219-
}
4227+
// If the parameter isn't given, use the env variable.
4228+
if (icu_data_dir.empty())
4229+
SafeGetenv("NODE_ICU_DATA", &icu_data_dir);
42204230
// Initialize ICU.
4221-
// If icu_data_dir is nullptr here, it will load the 'minimal' data.
4231+
// If icu_data_dir is empty here, it will load the 'minimal' data.
42224232
if (!i18n::InitializeICUDirectory(icu_data_dir)) {
42234233
FatalError(nullptr, "Could not initialize ICU "
42244234
"(check NODE_ICU_DATA or --icu-data-dir parameters)");
@@ -4483,8 +4493,11 @@ int Start(int argc, char** argv) {
44834493
Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
44844494

44854495
#if HAVE_OPENSSL
4486-
if (const char* extra = secure_getenv("NODE_EXTRA_CA_CERTS"))
4487-
crypto::UseExtraCaCerts(extra);
4496+
{
4497+
std::string extra_ca_certs;
4498+
if (SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs))
4499+
crypto::UseExtraCaCerts(extra_ca_certs);
4500+
}
44884501
#ifdef NODE_FIPS_MODE
44894502
// In the case of FIPS builds we should make sure
44904503
// the random source is properly initialized first.
@@ -4493,7 +4506,7 @@ int Start(int argc, char** argv) {
44934506
// V8 on Windows doesn't have a good source of entropy. Seed it from
44944507
// OpenSSL's pool.
44954508
V8::SetEntropySource(crypto::EntropySource);
4496-
#endif
4509+
#endif // HAVE_OPENSSL
44974510

44984511
v8_platform.Initialize(v8_thread_pool_size);
44994512
V8::Initialize();

src/node_i18n.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -404,12 +404,8 @@ static void GetVersion(const FunctionCallbackInfo<Value>& args) {
404404
}
405405
}
406406

407-
bool InitializeICUDirectory(const char* icu_data_path) {
408-
if (icu_data_path != nullptr) {
409-
flag_icu_data_dir = true;
410-
u_setDataDirectory(icu_data_path);
411-
return true; // no error
412-
} else {
407+
bool InitializeICUDirectory(const std::string& path) {
408+
if (path.empty()) {
413409
UErrorCode status = U_ZERO_ERROR;
414410
#ifdef NODE_HAVE_SMALL_ICU
415411
// install the 'small' data.
@@ -418,6 +414,10 @@ bool InitializeICUDirectory(const char* icu_data_path) {
418414
// no small data, so nothing to do.
419415
#endif // !NODE_HAVE_SMALL_ICU
420416
return (status == U_ZERO_ERROR);
417+
} else {
418+
flag_icu_data_dir = true;
419+
u_setDataDirectory(path.c_str());
420+
return true; // No error.
421421
}
422422
}
423423

src/node_i18n.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
55

66
#include "node.h"
7+
#include <string>
78

89
#if defined(NODE_HAVE_I18N_SUPPORT)
910

@@ -13,7 +14,7 @@ extern bool flag_icu_data_dir;
1314

1415
namespace i18n {
1516

16-
bool InitializeICUDirectory(const char* icu_data_path);
17+
bool InitializeICUDirectory(const std::string& path);
1718

1819
int32_t ToASCII(MaybeStackBuffer<char>* buf,
1920
const char* input,

src/node_internals.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <stdint.h>
1313
#include <stdlib.h>
1414

15+
#include <string>
16+
1517
struct sockaddr;
1618

1719
// Variation on NODE_DEFINE_CONSTANT that sets a String value.

0 commit comments

Comments
 (0)