From: Vsevolod Stakhov Date: Mon, 27 Oct 2025 12:45:34 +0000 (+0000) Subject: [Fix] Properly cleanup OpenSSL providers to prevent memory leak X-Git-Tag: 3.14.0~32^2~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c0e3b41a7d328aff968678aa28f634e14e9e4657;p=thirdparty%2Frspamd.git [Fix] Properly cleanup OpenSSL providers to prevent memory leak OpenSSL 3.0+ providers (legacy and default) were loaded but never unloaded, causing memory leaks detected by ASAN. This commit adds proper cleanup by: - Saving provider pointers when loading - Creating rspamd_openssl_cleanup() function to unload providers - Calling cleanup on main process termination --- diff --git a/src/libserver/ssl_util.c b/src/libserver/ssl_util.c index c0443ecd97..6d6046ba04 100644 --- a/src/libserver/ssl_util.c +++ b/src/libserver/ssl_util.c @@ -1056,6 +1056,8 @@ gpointer rspamd_init_ssl_ctx_noverify(void) } #if defined(RSPAMD_LEGACY_SSL_PROVIDER) && OPENSSL_VERSION_NUMBER >= 0x30000000L #include +static OSSL_PROVIDER *rspamd_legacy_provider = NULL; +static OSSL_PROVIDER *rspamd_default_provider = NULL; #endif void rspamd_openssl_maybe_init(void) @@ -1079,11 +1081,13 @@ void rspamd_openssl_maybe_init(void) OPENSSL_init_ssl(0, NULL); #endif #if defined(RSPAMD_LEGACY_SSL_PROVIDER) && OPENSSL_VERSION_NUMBER >= 0x30000000L - if (OSSL_PROVIDER_load(NULL, "legacy") == NULL) { + rspamd_legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); + if (rspamd_legacy_provider == NULL) { msg_err("cannot load legacy OpenSSL provider: %s", ERR_lib_error_string(ERR_get_error())); ERR_clear_error(); } - if (OSSL_PROVIDER_load(NULL, "default") == NULL) { + rspamd_default_provider = OSSL_PROVIDER_load(NULL, "default"); + if (rspamd_default_provider == NULL) { msg_err("cannot load default OpenSSL provider: %s", ERR_lib_error_string(ERR_get_error())); ERR_clear_error(); } @@ -1105,6 +1109,20 @@ void rspamd_openssl_maybe_init(void) } } +void rspamd_openssl_cleanup(void) +{ +#if defined(RSPAMD_LEGACY_SSL_PROVIDER) && OPENSSL_VERSION_NUMBER >= 0x30000000L + if (rspamd_legacy_provider) { + OSSL_PROVIDER_unload(rspamd_legacy_provider); + rspamd_legacy_provider = NULL; + } + if (rspamd_default_provider) { + OSSL_PROVIDER_unload(rspamd_default_provider); + rspamd_default_provider = NULL; + } +#endif +} + void rspamd_ssl_ctx_config(struct rspamd_config *cfg, gpointer ssl_ctx) { struct rspamd_ssl_ctx *ctx = (struct rspamd_ssl_ctx *) ssl_ctx; diff --git a/src/libserver/ssl_util.h b/src/libserver/ssl_util.h index 862ad460f9..15962cc072 100644 --- a/src/libserver/ssl_util.h +++ b/src/libserver/ssl_util.h @@ -112,6 +112,7 @@ gpointer rspamd_init_ssl_ctx_noverify(void); void rspamd_ssl_ctx_config(struct rspamd_config *cfg, gpointer ssl_ctx); void rspamd_ssl_ctx_free(gpointer ssl_ctx); void rspamd_openssl_maybe_init(void); +void rspamd_openssl_cleanup(void); #ifdef __cplusplus } diff --git a/src/rspamd.c b/src/rspamd.c index 58e35b9822..777c6261f4 100644 --- a/src/rspamd.c +++ b/src/rspamd.c @@ -24,6 +24,7 @@ #include "cryptobox.h" #include "utlist.h" #include "unix-std.h" +#include "libserver/ssl_util.h" /* pwd and grp */ #ifdef HAVE_PWD_H #include @@ -1740,6 +1741,7 @@ int main(int argc, char **argv, char **env) #endif REF_RELEASE(rspamd_main->cfg); rspamd_log_close(rspamd_main->logger); + rspamd_openssl_cleanup(); g_hash_table_unref(rspamd_main->spairs); g_hash_table_unref(rspamd_main->workers); rspamd_mempool_delete(rspamd_main->server_pool);