diff options
Diffstat (limited to 'patches/openssl-3.2.1/0004-conf-Serialize-allocation-free-of-ssl_names.patch')
-rw-r--r-- | patches/openssl-3.2.1/0004-conf-Serialize-allocation-free-of-ssl_names.patch | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/patches/openssl-3.2.1/0004-conf-Serialize-allocation-free-of-ssl_names.patch b/patches/openssl-3.2.1/0004-conf-Serialize-allocation-free-of-ssl_names.patch new file mode 100644 index 000000000..e9cabb5f9 --- /dev/null +++ b/patches/openssl-3.2.1/0004-conf-Serialize-allocation-free-of-ssl_names.patch @@ -0,0 +1,106 @@ +From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> +Date: Mon, 19 Sep 2022 20:51:31 +0200 +Subject: [PATCH] conf: Serialize allocation/free of ssl_names. + +The access to `ssl_names' is not fully serialized. With multiple threads +it is possible that more than one thread starts to clean up `ssl_names'. +This leads to occasional segfaults if more than one terminates and +performs the clean up. + +Fixes: #19243 + +Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> + +Imported from openssl_3.0.8-1.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + crypto/conf/conf_ssl.c | 35 ++++++++++++++++++++++++++++++++--- + 1 file changed, 32 insertions(+), 3 deletions(-) + +diff --git a/crypto/conf/conf_ssl.c b/crypto/conf/conf_ssl.c +index 84c5b2afe581..d6596e60c3b5 100644 +--- a/crypto/conf/conf_ssl.c ++++ b/crypto/conf/conf_ssl.c +@@ -12,6 +12,7 @@ + #include <openssl/conf.h> + #include <openssl/err.h> + #include "internal/sslconf.h" ++#include "internal/thread_once.h" + #include "conf_local.h" + + /* +@@ -35,12 +36,25 @@ struct ssl_conf_cmd_st { + char *arg; + }; + ++static CRYPTO_ONCE init_ssl_names_lock = CRYPTO_ONCE_STATIC_INIT; ++static CRYPTO_RWLOCK *ssl_names_lock; + static struct ssl_conf_name_st *ssl_names; + static size_t ssl_names_count; + +-static void ssl_module_free(CONF_IMODULE *md) ++DEFINE_RUN_ONCE_STATIC(do_init_ssl_names_lock) ++{ ++ ssl_names_lock = CRYPTO_THREAD_lock_new(); ++ if (ssl_names_lock == NULL) { ++ ERR_raise(ERR_LIB_CONF, ERR_R_MALLOC_FAILURE); ++ return 0; ++ } ++ return 1; ++} ++ ++static void ssl_module_free_unlocked(CONF_IMODULE *md) + { + size_t i, j; ++ + if (ssl_names == NULL) + return; + for (i = 0; i < ssl_names_count; i++) { +@@ -58,6 +72,14 @@ static void ssl_module_free(CONF_IMODULE *md) + ssl_names_count = 0; + } + ++static void ssl_module_free(CONF_IMODULE *md) ++{ ++ if (!CRYPTO_THREAD_write_lock(ssl_names_lock)) ++ return; ++ ssl_module_free_unlocked(md); ++ CRYPTO_THREAD_unlock(ssl_names_lock); ++} ++ + static int ssl_module_init(CONF_IMODULE *md, const CONF *cnf) + { + size_t i, j, cnt; +@@ -65,6 +87,12 @@ static int ssl_module_init(CONF_IMODULE *md, const CONF *cnf) + const char *ssl_conf_section; + STACK_OF(CONF_VALUE) *cmd_lists; + ++ if (!RUN_ONCE(&init_ssl_names_lock, do_init_ssl_names_lock)) ++ return 0; ++ ++ if (!CRYPTO_THREAD_write_lock(ssl_names_lock)) ++ return 0; ++ + ssl_conf_section = CONF_imodule_get_value(md); + cmd_lists = NCONF_get_section(cnf, ssl_conf_section); + if (sk_CONF_VALUE_num(cmd_lists) <= 0) { +@@ -77,7 +105,7 @@ static int ssl_module_init(CONF_IMODULE *md, const CONF *cnf) + goto err; + } + cnt = sk_CONF_VALUE_num(cmd_lists); +- ssl_module_free(md); ++ ssl_module_free_unlocked(md); + ssl_names = OPENSSL_zalloc(sizeof(*ssl_names) * cnt); + if (ssl_names == NULL) + goto err; +@@ -126,7 +154,8 @@ static int ssl_module_init(CONF_IMODULE *md, const CONF *cnf) + rv = 1; + err: + if (rv == 0) +- ssl_module_free(md); ++ ssl_module_free_unlocked(md); ++ CRYPTO_THREAD_unlock(ssl_names_lock); + return rv; + } + |