]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] Properly cleanup OpenSSL providers to prevent memory leak
authorVsevolod Stakhov <vsevolod@rspamd.com>
Mon, 27 Oct 2025 12:45:34 +0000 (12:45 +0000)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Mon, 27 Oct 2025 12:45:34 +0000 (12:45 +0000)
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

src/libserver/ssl_util.c
src/libserver/ssl_util.h
src/rspamd.c

index c0443ecd97551f57b714b3d5a18c70ac7535a544..6d6046ba04363b90243f5dd7d3e4f0c1042639d6 100644 (file)
@@ -1056,6 +1056,8 @@ gpointer rspamd_init_ssl_ctx_noverify(void)
 }
 #if defined(RSPAMD_LEGACY_SSL_PROVIDER) && OPENSSL_VERSION_NUMBER >= 0x30000000L
 #include <openssl/provider.h>
+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;
index 862ad460f9750eb35e48c6ece7efe6d2451391bd..15962cc07249f6b50fac7fa65f9c5b7a983db650 100644 (file)
@@ -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
 }
index 58e35b9822aca2ac287df3ec9360a82e38b697ec..777c6261f44b2a6530dc1bcd016cc2bdeb86d753 100644 (file)
@@ -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 <pwd.h>
@@ -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);