Commit 21f2aa66bc for openssl.org
commit 21f2aa66bca86bb3a5b786135495b074415243db
Author: Neil Horman <nhorman@openssl.org>
Date: Thu Oct 1 10:43:20 2026 -0400
add provider load_unload / doall test
Add a test to torture loading/unloading of a provider while we run
parallel calls to OSSL_DECODER_do_all
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Merge-date: Mon Oct 5 09:31:07 2026
Merged-from: https://github.com/openssl/openssl/pull/33056
diff --git a/test/threadstest.c b/test/threadstest.c
index 65c7afcae6..2c0877341d 100644
--- a/test/threadstest.c
+++ b/test/threadstest.c
@@ -27,6 +27,7 @@
#include <openssl/rand.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
+#include <openssl/decoder.h>
#include "internal/tsan_assist.h"
#include "internal/nelem.h"
#include "internal/time.h"
@@ -1502,6 +1503,92 @@ static void test_obj_create_worker(void)
}
}
+#if defined(OPENSSL_THREADS)
+static thread_t do_all_thread;
+static thread_t load_unload_thread;
+static OSSL_LIB_CTX *do_all_ctx = NULL;
+static OSSL_PROVIDER *defprov = NULL;
+static int load_unload_err = 0;
+static int do_all_err = 0;
+
+static void do_all_fn(void)
+{
+ OSSL_TIME t1, t2;
+ EVP_PKEY *pkey = NULL;
+ OSSL_DECODER_CTX *dctx = NULL;
+
+ t1 = ossl_time_now();
+
+ for (;;) {
+ dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "PEM", NULL, "RSA",
+ EVP_PKEY_KEYPAIR,
+ do_all_ctx, "");
+ EVP_PKEY_free(pkey);
+ OSSL_DECODER_CTX_free(dctx);
+ t2 = ossl_time_now();
+ if ((ossl_time2seconds(t2) - ossl_time2seconds(t1)) >= TORTURE_SECONDS)
+ break;
+ }
+ do_all_err = 0;
+ return;
+}
+
+static void load_unload_fn(void)
+{
+ OSSL_TIME t1, t2;
+
+ t1 = ossl_time_now();
+
+ for (;;) {
+ if (defprov == NULL) {
+ defprov = OSSL_PROVIDER_load(do_all_ctx, "default");
+ if (!TEST_ptr(defprov)) {
+ load_unload_err = 1;
+ return;
+ }
+ } else {
+ if (!TEST_true(OSSL_PROVIDER_unload(defprov))) {
+ load_unload_err = 1;
+ return;
+ }
+ defprov = NULL;
+ }
+ t2 = ossl_time_now();
+ if ((ossl_time2seconds(t2) - ossl_time2seconds(t1)) >= TORTURE_SECONDS)
+ break;
+ }
+ if (defprov != NULL)
+ OSSL_PROVIDER_unload(defprov);
+ return;
+}
+
+static int test_do_all_stress(void)
+{
+ do_all_ctx = OSSL_LIB_CTX_new();
+ int ret = 0;
+
+ if (!TEST_ptr(do_all_ctx))
+ goto err;
+
+ if (!TEST_true(run_thread(&load_unload_thread, load_unload_fn))
+ || !TEST_true(run_thread(&do_all_thread, do_all_fn))
+ || !TEST_true(wait_for_thread(load_unload_thread))
+ || !TEST_true(wait_for_thread(do_all_thread)))
+ goto err;
+
+ if (!TEST_int_eq(load_unload_err, 0))
+ goto err;
+
+ if (!TEST_int_eq(do_all_err, 0))
+ goto err;
+
+ ret = 1;
+err:
+ OSSL_LIB_CTX_free(do_all_ctx);
+ return ret;
+}
+#endif
+
static int test_obj_stress(void)
{
return thread_run_test(&test_obj_create_worker, MAXIMUM_THREADS,
@@ -1577,6 +1664,7 @@ int setup_tests(void)
ADD_TEST(torture_rcu_low);
ADD_TEST(torture_rcu_high);
ADD_TEST(torture_rcu_high2);
+ ADD_TEST(test_do_all_stress);
#endif
ADD_TEST(test_once);
ADD_TEST(test_thread_local);