1 From: David Woodhouse <dwmw2@infradead.org>
2 Date: Wed, 13 May 2020 13:13:34 +0100
3 Subject: Fix OPENSSL_cleanup() detection without using our own atexit()
6 We can't register our own atexit() or OPENSSL_atexit() handler because
7 there's no way to unregister it when the SoftHSM DSO is unloaded. This
8 causes the crash reported at https://bugzilla.redhat.com/1831086#c8
10 Instead of using that method to set a flag showing that OPENSSL_cleanup()
11 has occurred, instead test directly by calling OPENSSL_init_crypto() for
12 something that *would* do nothing, but will fail if OPENSSL_cleanup()
13 has indeed been run already.
15 Fixes: c2cc0652b4 "Issue #548: Don't clean up engines after OpenSSL
16 has already shut down"
18 src/lib/crypto/OSSLCryptoFactory.cpp | 40 ++++++++++++++----------------------
19 1 file changed, 15 insertions(+), 25 deletions(-)
21 diff --git a/src/lib/crypto/OSSLCryptoFactory.cpp b/src/lib/crypto/OSSLCryptoFactory.cpp
22 index 81d080a..ace4bcb 100644
23 --- a/src/lib/crypto/OSSLCryptoFactory.cpp
24 +++ b/src/lib/crypto/OSSLCryptoFactory.cpp
25 @@ -77,7 +77,6 @@ bool OSSLCryptoFactory::FipsSelfTestStatus = false;
27 static unsigned nlocks;
29 -static bool ossl_shutdown;
32 void lock_callback(int mode, int n, const char* file, int line)
33 @@ -102,26 +101,6 @@ void lock_callback(int mode, int n, const char* file, int line)
37 -#if OPENSSL_VERSION_NUMBER >= 0x10100000L
38 -void ossl_factory_shutdown(void)
41 - * As of 1.1.0, OpenSSL registers its own atexit() handler
42 - * to call OPENSSL_cleanup(). If our own atexit() handler
43 - * subsequently tries to, for example, unreference an
44 - * ENGINE, then it'll crash or deadlock with a use-after-free.
46 - * This hook into the OpenSSL_atexit() handlers will get called
47 - * when OPENSSL_cleanup() is called, and sets a flag which
48 - * prevents any further touching of OpenSSL objects — which
49 - * would otherwise happen fairly much immediately thereafter
50 - * when our own OSSLCryptoFactory destructor gets called by
51 - * the C++ runtime's own atexit() handler.
53 - ossl_shutdown = true;
58 OSSLCryptoFactory::OSSLCryptoFactory()
60 @@ -140,9 +119,6 @@ OSSLCryptoFactory::OSSLCryptoFactory()
61 CRYPTO_set_locking_callback(lock_callback);
62 setLockingCallback = true;
65 - // Mustn't dereference engines after OpenSSL itself has shut down
66 - OPENSSL_atexit(ossl_factory_shutdown);
70 @@ -250,7 +226,21 @@ err:
72 OSSLCryptoFactory::~OSSLCryptoFactory()
74 - // Don't do this if OPENSSL_cleanup() has already happened
75 + bool ossl_shutdown = false;
77 +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
78 + // OpenSSL 1.1.0+ will register an atexit() handler to run
79 + // OPENSSL_cleanup(). If that has already happened we must
80 + // not attempt to free any ENGINEs because they'll already
81 + // have been destroyed and the use-after-free would cause
82 + // a deadlock or crash.
84 + // Detect that situation because reinitialisation will fail
85 + // after OPENSSL_cleanup() has run.
86 + (void)ERR_set_mark();
87 + ossl_shutdown = !OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_RDRAND, NULL);
88 + (void)ERR_pop_to_mark();