mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
src: make InitializeOncePerProcess more flexible
PR-URL: https://github.com/nodejs/node/pull/38888 Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
118
src/node.cc
118
src/node.cc
@@ -233,7 +233,7 @@ int Environment::InitializeInspector(
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif // HAVE_INSPECTOR && NODE_USE_V8_PLATFORM
|
||||
#endif // HAVE_INSPECTOR
|
||||
|
||||
#define ATOMIC_WAIT_EVENTS(V) \
|
||||
V(kStartWait, "started") \
|
||||
@@ -957,12 +957,26 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv,
|
||||
}
|
||||
|
||||
InitializationResult InitializeOncePerProcess(int argc, char** argv) {
|
||||
return InitializeOncePerProcess(argc, argv, kDefaultInitialization);
|
||||
}
|
||||
|
||||
InitializationResult InitializeOncePerProcess(
|
||||
int argc,
|
||||
char** argv,
|
||||
InitializationSettingsFlags flags) {
|
||||
uint64_t init_flags = flags;
|
||||
if (init_flags & kDefaultInitialization) {
|
||||
init_flags = init_flags | kInitializeV8 | kInitOpenSSL | kRunPlatformInit;
|
||||
}
|
||||
|
||||
// Initialized the enabled list for Debug() calls with system
|
||||
// environment variables.
|
||||
per_process::enabled_debug_list.Parse(nullptr);
|
||||
|
||||
atexit(ResetStdio);
|
||||
PlatformInit();
|
||||
|
||||
if (init_flags & kRunPlatformInit)
|
||||
PlatformInit();
|
||||
|
||||
CHECK_GT(argc, 0);
|
||||
|
||||
@@ -1015,65 +1029,71 @@ InitializationResult InitializeOncePerProcess(int argc, char** argv) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (init_flags & kInitOpenSSL) {
|
||||
#if HAVE_OPENSSL
|
||||
{
|
||||
std::string extra_ca_certs;
|
||||
if (credentials::SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs))
|
||||
crypto::UseExtraCaCerts(extra_ca_certs);
|
||||
}
|
||||
// In the case of FIPS builds we should make sure
|
||||
// the random source is properly initialized first.
|
||||
{
|
||||
std::string extra_ca_certs;
|
||||
if (credentials::SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs))
|
||||
crypto::UseExtraCaCerts(extra_ca_certs);
|
||||
}
|
||||
// In the case of FIPS builds we should make sure
|
||||
// the random source is properly initialized first.
|
||||
#if OPENSSL_VERSION_MAJOR >= 3
|
||||
// Call OPENSSL_init_crypto to initialize OPENSSL_INIT_LOAD_CONFIG to
|
||||
// avoid the default behavior where errors raised during the parsing of the
|
||||
// OpenSSL configuration file are not propagated and cannot be detected.
|
||||
//
|
||||
// If FIPS is configured the OpenSSL configuration file will have an .include
|
||||
// pointing to the fipsmodule.cnf file generated by the openssl fipsinstall
|
||||
// command. If the path to this file is incorrect no error will be reported.
|
||||
//
|
||||
// For Node.js this will mean that EntropySource will be called by V8 as part
|
||||
// of its initialization process, and EntropySource will in turn call
|
||||
// CheckEntropy. CheckEntropy will call RAND_status which will now always
|
||||
// return 0, leading to an endless loop and the node process will appear to
|
||||
// hang/freeze.
|
||||
std::string env_openssl_conf;
|
||||
credentials::SafeGetenv("OPENSSL_CONF", &env_openssl_conf);
|
||||
// Call OPENSSL_init_crypto to initialize OPENSSL_INIT_LOAD_CONFIG to
|
||||
// avoid the default behavior where errors raised during the parsing of the
|
||||
// OpenSSL configuration file are not propagated and cannot be detected.
|
||||
//
|
||||
// If FIPS is configured the OpenSSL configuration file will have an
|
||||
// .include pointing to the fipsmodule.cnf file generated by the openssl
|
||||
// fipsinstall command. If the path to this file is incorrect no error
|
||||
// will be reported.
|
||||
//
|
||||
// For Node.js this will mean that EntropySource will be called by V8 as
|
||||
// part of its initialization process, and EntropySource will in turn call
|
||||
// CheckEntropy. CheckEntropy will call RAND_status which will now always
|
||||
// return 0, leading to an endless loop and the node process will appear to
|
||||
// hang/freeze.
|
||||
std::string env_openssl_conf;
|
||||
credentials::SafeGetenv("OPENSSL_CONF", &env_openssl_conf);
|
||||
|
||||
bool has_cli_conf = !per_process::cli_options->openssl_config.empty();
|
||||
if (has_cli_conf || !env_openssl_conf.empty()) {
|
||||
OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();
|
||||
OPENSSL_INIT_set_config_file_flags(settings, CONF_MFLAGS_DEFAULT_SECTION);
|
||||
if (has_cli_conf) {
|
||||
const char* conf = per_process::cli_options->openssl_config.c_str();
|
||||
OPENSSL_INIT_set_config_filename(settings, conf);
|
||||
}
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, settings);
|
||||
OPENSSL_INIT_free(settings);
|
||||
bool has_cli_conf = !per_process::cli_options->openssl_config.empty();
|
||||
if (has_cli_conf || !env_openssl_conf.empty()) {
|
||||
OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();
|
||||
OPENSSL_INIT_set_config_file_flags(settings, CONF_MFLAGS_DEFAULT_SECTION);
|
||||
if (has_cli_conf) {
|
||||
const char* conf = per_process::cli_options->openssl_config.c_str();
|
||||
OPENSSL_INIT_set_config_filename(settings, conf);
|
||||
}
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, settings);
|
||||
OPENSSL_INIT_free(settings);
|
||||
|
||||
if (ERR_peek_error() != 0) {
|
||||
result.exit_code = ERR_GET_REASON(ERR_peek_error());
|
||||
result.early_return = true;
|
||||
fprintf(stderr, "OpenSSL configuration error:\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
return result;
|
||||
if (ERR_peek_error() != 0) {
|
||||
result.exit_code = ERR_GET_REASON(ERR_peek_error());
|
||||
result.early_return = true;
|
||||
fprintf(stderr, "OpenSSL configuration error:\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (FIPS_mode()) {
|
||||
OPENSSL_init();
|
||||
}
|
||||
if (FIPS_mode()) {
|
||||
OPENSSL_init();
|
||||
}
|
||||
#endif
|
||||
// V8 on Windows doesn't have a good source of entropy. Seed it from
|
||||
// OpenSSL's pool.
|
||||
V8::SetEntropySource(crypto::EntropySource);
|
||||
// V8 on Windows doesn't have a good source of entropy. Seed it from
|
||||
// OpenSSL's pool.
|
||||
V8::SetEntropySource(crypto::EntropySource);
|
||||
#endif // HAVE_OPENSSL
|
||||
|
||||
}
|
||||
per_process::v8_platform.Initialize(
|
||||
static_cast<int>(per_process::cli_options->v8_thread_pool_size));
|
||||
V8::Initialize();
|
||||
if (init_flags & kInitializeV8) {
|
||||
V8::Initialize();
|
||||
}
|
||||
|
||||
performance::performance_v8_start = PERFORMANCE_NOW();
|
||||
per_process::v8_initialized = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -316,7 +316,20 @@ struct InitializationResult {
|
||||
std::vector<std::string> exec_args;
|
||||
bool early_return = false;
|
||||
};
|
||||
|
||||
enum InitializationSettingsFlags : uint64_t {
|
||||
kDefaultInitialization = 1 << 0,
|
||||
kInitializeV8 = 1 << 1,
|
||||
kRunPlatformInit = 1 << 2,
|
||||
kInitOpenSSL = 1 << 3
|
||||
};
|
||||
|
||||
// TODO(codebytere): eventually document and expose to embedders.
|
||||
InitializationResult InitializeOncePerProcess(int argc, char** argv);
|
||||
InitializationResult InitializeOncePerProcess(
|
||||
int argc,
|
||||
char** argv,
|
||||
InitializationSettingsFlags flags);
|
||||
void TearDownOncePerProcess();
|
||||
void SetIsolateErrorHandlers(v8::Isolate* isolate, const IsolateSettings& s);
|
||||
void SetIsolateMiscHandlers(v8::Isolate* isolate, const IsolateSettings& s);
|
||||
|
||||
Reference in New Issue
Block a user