From 456c1860cfe4080958f981ef53e9bb04fce76269 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sun, 3 Apr 2022 14:00:27 +0200 Subject: [PATCH] src: add proper mutexes for accessing FIPS state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FIPS state handling and OpenSSL initialization code makes accesses to global OpenSSL state without any protection against parallel modifications from multiple threads. This commit adds such protections. PR-URL: https://github.com/nodejs/node/pull/42278 Reviewed-By: Tobias Nießen Reviewed-By: Richard Lau Reviewed-By: James M Snell Reviewed-By: Darshan Sen --- src/crypto/crypto_util.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc index e1ef170a9f1763..7b3015d9d78b7d 100644 --- a/src/crypto/crypto_util.cc +++ b/src/crypto/crypto_util.cc @@ -136,7 +136,13 @@ bool InitCryptoOnce(Isolate* isolate) { return true; } +// Protect accesses to FIPS state with a mutex. This should potentially +// be part of a larger mutex for global OpenSSL state. +static Mutex fips_mutex; + void InitCryptoOnce() { + Mutex::ScopedLock lock(per_process::cli_options_mutex); + Mutex::ScopedLock fips_lock(fips_mutex); #ifndef OPENSSL_IS_BORINGSSL OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new(); @@ -186,6 +192,9 @@ void InitCryptoOnce() { } void GetFipsCrypto(const FunctionCallbackInfo& args) { + Mutex::ScopedLock lock(per_process::cli_options_mutex); + Mutex::ScopedLock fips_lock(fips_mutex); + #if OPENSSL_VERSION_MAJOR >= 3 args.GetReturnValue().Set(EVP_default_properties_is_fips_enabled(nullptr) ? 1 : 0); @@ -195,8 +204,13 @@ void GetFipsCrypto(const FunctionCallbackInfo& args) { } void SetFipsCrypto(const FunctionCallbackInfo& args) { + Mutex::ScopedLock lock(per_process::cli_options_mutex); + Mutex::ScopedLock fips_lock(fips_mutex); + CHECK(!per_process::cli_options->force_fips_crypto); Environment* env = Environment::GetCurrent(args); + // TODO(addaleax): This should not be possible to set from worker threads. + // CHECK(env->owns_process_state()); bool enable = args[0]->BooleanValue(env->isolate()); #if OPENSSL_VERSION_MAJOR >= 3 @@ -217,6 +231,9 @@ void SetFipsCrypto(const FunctionCallbackInfo& args) { } void TestFipsCrypto(const v8::FunctionCallbackInfo& args) { + Mutex::ScopedLock lock(per_process::cli_options_mutex); + Mutex::ScopedLock fips_lock(fips_mutex); + #ifdef OPENSSL_FIPS #if OPENSSL_VERSION_MAJOR >= 3 OSSL_PROVIDER* fips_provider = nullptr;