summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Grulich <jgrulich@redhat.com>2023-07-16 11:31:24 +0200
committerJan Grulich <jgrulich@redhat.com>2023-10-02 16:34:31 +0200
commite25c773f2b7e5ee303eac27da09b11ecbcb8a05a (patch)
tree4bf43387e6ac7c9b28bb833f99d817a7d66f68bc
parentcd7c1037c2da6fc47d4956f313106e6270c11b7c (diff)
QCryptographicHash: don't forget to unload OpenSSL providers
Automatically unload loaded crypto providers on cleanup. In most cases we don't load them, but when we do (e.g. when MD4 is used), we would be leaking memory. Fixes: QTBUG-115233 Pick-to: 6.5 6.6 Change-Id: I91318d391ab35d00647d1e9e2408fc987811a2d3 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
-rw-r--r--src/corelib/tools/qcryptographichash.cpp20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
index 6986601b9f..bec5cf9df1 100644
--- a/src/corelib/tools/qcryptographichash.cpp
+++ b/src/corelib/tools/qcryptographichash.cpp
@@ -326,11 +326,20 @@ public:
EVP_MD_free(md);
}
};
+ struct OSSL_PROVIDER_deleter {
+ void operator()(OSSL_PROVIDER *provider) const noexcept {
+ OSSL_PROVIDER_unload(provider);
+ }
+ };
+
using EVP_MD_CTX_ptr = std::unique_ptr<EVP_MD_CTX, EVP_MD_CTX_deleter>;
using EVP_MD_ptr = std::unique_ptr<EVP_MD, EVP_MD_deleter>;
+ using OSSL_PROVIDER_ptr = std::unique_ptr<OSSL_PROVIDER, OSSL_PROVIDER_deleter>;
struct EVP {
EVP_MD_ptr algorithm;
EVP_MD_CTX_ptr context;
+ OSSL_PROVIDER_ptr defaultProvider;
+ OSSL_PROVIDER_ptr legacyProvider;
bool initializationFailed;
explicit EVP(QCryptographicHash::Algorithm method);
@@ -583,9 +592,10 @@ QCryptographicHashPrivate::EVP::EVP(QCryptographicHash::Algorithm method)
* We need to load the legacy provider in order to have the MD4
* algorithm available.
*/
- if (!OSSL_PROVIDER_load(nullptr, "legacy"))
- return;
- if (!OSSL_PROVIDER_load(nullptr, "default"))
+ legacyProvider = OSSL_PROVIDER_ptr(OSSL_PROVIDER_load(nullptr, "legacy"));
+ defaultProvider = OSSL_PROVIDER_ptr(OSSL_PROVIDER_load(nullptr, "default"));
+
+ if (!legacyProvider || !defaultProvider)
return;
}
@@ -1163,8 +1173,8 @@ bool QCryptographicHashPrivate::supportsAlgorithm(QCryptographicHash::Algorithm
if (useNonOpenSSLFallback(method))
return true;
- OSSL_PROVIDER_load(nullptr, "legacy");
- OSSL_PROVIDER_load(nullptr, "default");
+ auto legacyProvider = OSSL_PROVIDER_ptr(OSSL_PROVIDER_load(nullptr, "legacy"));
+ auto defaultProvider = OSSL_PROVIDER_ptr(OSSL_PROVIDER_load(nullptr, "default"));
const char *restriction = "-fips";
EVP_MD_ptr algorithm = EVP_MD_ptr(EVP_MD_fetch(nullptr, methodToName(method), restriction));