Skip to content

Commit aa245e2

Browse files
committed
src: make InitializeOncePerProcess more flexible
1 parent 21f5a56 commit aa245e2

File tree

2 files changed

+84
-51
lines changed

2 files changed

+84
-51
lines changed

src/node.cc

Lines changed: 71 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ int Environment::InitializeInspector(
233233

234234
return 0;
235235
}
236-
#endif // HAVE_INSPECTOR && NODE_USE_V8_PLATFORM
236+
#endif // HAVE_INSPECTOR
237237

238238
#define ATOMIC_WAIT_EVENTS(V) \
239239
V(kStartWait, "started") \
@@ -957,12 +957,26 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv,
957957
}
958958

959959
InitializationResult InitializeOncePerProcess(int argc, char** argv) {
960+
return InitializeOncePerProcess(argc, argv, kDefaultInitialization);
961+
}
962+
963+
InitializationResult InitializeOncePerProcess(
964+
int argc,
965+
char** argv,
966+
InitializationSettingsFlags flags) {
967+
uint64_t init_flags = flags;
968+
if (init_flags & kDefaultInitialization) {
969+
init_flags = init_flags | kInitializeV8 | kInitOpenSSL | kRunPlatformInit;
970+
}
971+
960972
// Initialized the enabled list for Debug() calls with system
961973
// environment variables.
962974
per_process::enabled_debug_list.Parse(nullptr);
963975

964976
atexit(ResetStdio);
965-
PlatformInit();
977+
978+
if (init_flags & kRunPlatformInit)
979+
PlatformInit();
966980

967981
CHECK_GT(argc, 0);
968982

@@ -1015,65 +1029,71 @@ InitializationResult InitializeOncePerProcess(int argc, char** argv) {
10151029
return result;
10161030
}
10171031

1032+
if (init_flags & kInitOpenSSL) {
10181033
#if HAVE_OPENSSL
1019-
{
1020-
std::string extra_ca_certs;
1021-
if (credentials::SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs))
1022-
crypto::UseExtraCaCerts(extra_ca_certs);
1023-
}
1024-
// In the case of FIPS builds we should make sure
1025-
// the random source is properly initialized first.
1026-
#if OPENSSL_VERSION_MAJOR >= 3
1027-
// Call OPENSSL_init_crypto to initialize OPENSSL_INIT_LOAD_CONFIG to
1028-
// avoid the default behavior where errors raised during the parsing of the
1029-
// OpenSSL configuration file are not propagated and cannot be detected.
1030-
//
1031-
// If FIPS is configured the OpenSSL configuration file will have an .include
1032-
// pointing to the fipsmodule.cnf file generated by the openssl fipsinstall
1033-
// command. If the path to this file is incorrect no error will be reported.
1034-
//
1035-
// For Node.js this will mean that EntropySource will be called by V8 as part
1036-
// of its initialization process, and EntropySource will in turn call
1037-
// CheckEntropy. CheckEntropy will call RAND_status which will now always
1038-
// return 0, leading to an endless loop and the node process will appear to
1039-
// hang/freeze.
1040-
std::string env_openssl_conf;
1041-
credentials::SafeGetenv("OPENSSL_CONF", &env_openssl_conf);
1042-
1043-
bool has_cli_conf = !per_process::cli_options->openssl_config.empty();
1044-
if (has_cli_conf || !env_openssl_conf.empty()) {
1045-
OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();
1046-
OPENSSL_INIT_set_config_file_flags(settings, CONF_MFLAGS_DEFAULT_SECTION);
1047-
if (has_cli_conf) {
1048-
const char* conf = per_process::cli_options->openssl_config.c_str();
1049-
OPENSSL_INIT_set_config_filename(settings, conf);
1034+
{
1035+
std::string extra_ca_certs;
1036+
if (credentials::SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs))
1037+
crypto::UseExtraCaCerts(extra_ca_certs);
10501038
}
1051-
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, settings);
1052-
OPENSSL_INIT_free(settings);
1053-
1054-
if (ERR_peek_error() != 0) {
1055-
result.exit_code = ERR_GET_REASON(ERR_peek_error());
1056-
result.early_return = true;
1057-
fprintf(stderr, "OpenSSL configuration error:\n");
1058-
ERR_print_errors_fp(stderr);
1059-
return result;
1039+
// In the case of FIPS builds we should make sure
1040+
// the random source is properly initialized first.
1041+
#if OPENSSL_VERSION_MAJOR >= 3
1042+
// Call OPENSSL_init_crypto to initialize OPENSSL_INIT_LOAD_CONFIG to
1043+
// avoid the default behavior where errors raised during the parsing of the
1044+
// OpenSSL configuration file are not propagated and cannot be detected.
1045+
//
1046+
// If FIPS is configured the OpenSSL configuration file will have an
1047+
// .include pointing to the fipsmodule.cnf file generated by the openssl
1048+
// fipsinstall command. If the path to this file is incorrect no error
1049+
// will be reported.
1050+
//
1051+
// For Node.js this will mean that EntropySource will be called by V8 as
1052+
// part of its initialization process, and EntropySource will in turn call
1053+
// CheckEntropy. CheckEntropy will call RAND_status which will now always
1054+
// return 0, leading to an endless loop and the node process will appear to
1055+
// hang/freeze.
1056+
std::string env_openssl_conf;
1057+
credentials::SafeGetenv("OPENSSL_CONF", &env_openssl_conf);
1058+
1059+
bool has_cli_conf = !per_process::cli_options->openssl_config.empty();
1060+
if (has_cli_conf || !env_openssl_conf.empty()) {
1061+
OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();
1062+
OPENSSL_INIT_set_config_file_flags(settings, CONF_MFLAGS_DEFAULT_SECTION);
1063+
if (has_cli_conf) {
1064+
const char* conf = per_process::cli_options->openssl_config.c_str();
1065+
OPENSSL_INIT_set_config_filename(settings, conf);
1066+
}
1067+
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, settings);
1068+
OPENSSL_INIT_free(settings);
1069+
1070+
if (ERR_peek_error() != 0) {
1071+
result.exit_code = ERR_GET_REASON(ERR_peek_error());
1072+
result.early_return = true;
1073+
fprintf(stderr, "OpenSSL configuration error:\n");
1074+
ERR_print_errors_fp(stderr);
1075+
return result;
1076+
}
10601077
}
1061-
}
10621078
#else
1063-
if (FIPS_mode()) {
1064-
OPENSSL_init();
1065-
}
1079+
if (FIPS_mode()) {
1080+
OPENSSL_init();
1081+
}
10661082
#endif
1067-
// V8 on Windows doesn't have a good source of entropy. Seed it from
1068-
// OpenSSL's pool.
1069-
V8::SetEntropySource(crypto::EntropySource);
1083+
// V8 on Windows doesn't have a good source of entropy. Seed it from
1084+
// OpenSSL's pool.
1085+
V8::SetEntropySource(crypto::EntropySource);
10701086
#endif // HAVE_OPENSSL
1071-
1087+
}
10721088
per_process::v8_platform.Initialize(
10731089
static_cast<int>(per_process::cli_options->v8_thread_pool_size));
1074-
V8::Initialize();
1090+
if (init_flags & kInitializeV8) {
1091+
V8::Initialize();
1092+
}
1093+
10751094
performance::performance_v8_start = PERFORMANCE_NOW();
10761095
per_process::v8_initialized = true;
1096+
10771097
return result;
10781098
}
10791099

src/node_internals.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,20 @@ struct InitializationResult {
316316
std::vector<std::string> exec_args;
317317
bool early_return = false;
318318
};
319+
320+
enum InitializationSettingsFlags : uint64_t {
321+
kDefaultInitialization = 1 << 0,
322+
kInitializeV8 = 1 << 1,
323+
kRunPlatformInit = 1 << 2,
324+
kInitOpenSSL = 1 << 3
325+
};
326+
327+
// TODO(codebytere): eventually document and expose to embedders.
319328
InitializationResult InitializeOncePerProcess(int argc, char** argv);
329+
InitializationResult InitializeOncePerProcess(
330+
int argc,
331+
char** argv,
332+
InitializationSettingsFlags flags);
320333
void TearDownOncePerProcess();
321334
void SetIsolateErrorHandlers(v8::Isolate* isolate, const IsolateSettings& s);
322335
void SetIsolateMiscHandlers(v8::Isolate* isolate, const IsolateSettings& s);

0 commit comments

Comments
 (0)