Commit f3f163243a for openssl.org
commit f3f163243a4fd6f5caea7bdb5ecc655f8c600cbb
Author: Tomas Mraz <tomas@openssl.foundation>
Date: Tue Jun 16 12:45:19 2026 +0200
Revert "convert CRYPTO_THREAD_run_once to use InitOnceExecuteOnce api"
This reverts commit d053fe41a4add4e55dc5633e8aef6602a6a4b90b.
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
MergeDate: Wed Jun 17 12:14:58 2026
(Merged from https://github.com/openssl/openssl/pull/31539)
diff --git a/crypto/threads_win.c b/crypto/threads_win.c
index d803b7221d..4fedf24e90 100644
--- a/crypto/threads_win.c
+++ b/crypto/threads_win.c
@@ -512,28 +512,32 @@ void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock)
return;
}
-struct init_once_cb_info {
- void (*init)(void);
-};
-
-static BOOL CALLBACK init_wrapper(PINIT_ONCE InitOnce, PVOID param, PVOID *context)
-{
- struct init_once_cb_info *info = (struct init_once_cb_info *)param;
-
- info->init();
- return TRUE;
-}
+#define ONCE_UNINITED 0
+#define ONCE_ININIT 1
+#define ONCE_DONE 2
+/*
+ * We don't use InitOnceExecuteOnce because that isn't available in WinXP which
+ * we still have to support.
+ */
int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
{
- INIT_ONCE *myonce = (INIT_ONCE *)once;
- struct init_once_cb_info info = { init };
- BOOL bstatus;
+ LONG volatile *lock = (LONG *)once;
+ LONG result;
- bstatus = InitOnceExecuteOnce(myonce, init_wrapper, (void *)&info, NULL);
- if (bstatus == TRUE)
+ if (*lock == ONCE_DONE)
return 1;
- return 0;
+
+ do {
+ result = InterlockedCompareExchange(lock, ONCE_ININIT, ONCE_UNINITED);
+ if (result == ONCE_UNINITED) {
+ init();
+ *lock = ONCE_DONE;
+ return 1;
+ }
+ } while (result == ONCE_ININIT);
+
+ return (*lock == ONCE_DONE);
}
int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
diff --git a/include/internal/e_os.h b/include/internal/e_os.h
index f0de2f363c..3ea75209cf 100644
--- a/include/internal/e_os.h
+++ b/include/internal/e_os.h
@@ -109,7 +109,7 @@
* 0x0603 // Windows 8.1
* 0x0A00 // Windows 10
*/
-#define _WIN32_WINNT 0x0600
+#define _WIN32_WINNT 0x0501
#endif
#include <windows.h>
#include <stdio.h>
diff --git a/include/openssl/crypto.h.in b/include/openssl/crypto.h.in
index 071b11b3bc..a9ade25b15 100644
--- a/include/openssl/crypto.h.in
+++ b/include/openssl/crypto.h.in
@@ -543,8 +543,8 @@ void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings);
typedef DWORD CRYPTO_THREAD_LOCAL;
typedef DWORD CRYPTO_THREAD_ID;
-typedef INIT_ONCE CRYPTO_ONCE;
-#define CRYPTO_ONCE_STATIC_INIT INIT_ONCE_STATIC_INIT
+typedef LONG CRYPTO_ONCE;
+#define CRYPTO_ONCE_STATIC_INIT 0
#endif
#else
#if defined(__TANDEM) && defined(_SPT_MODEL_)
diff --git a/include/openssl/e_os2.h b/include/openssl/e_os2.h
index 698f2da26b..bacc161bd6 100644
--- a/include/openssl/e_os2.h
+++ b/include/openssl/e_os2.h
@@ -58,7 +58,6 @@ extern "C" {
#define OPENSSL_SYS_WIN32_CYGWIN
#else
#if defined(_WIN32) || defined(OPENSSL_SYS_WIN32)
-#include "windows.h"
#undef OPENSSL_SYS_UNIX
#if !defined(OPENSSL_SYS_WIN32)
#define OPENSSL_SYS_WIN32
diff --git a/providers/implementations/rands/seeding/rand_win.c b/providers/implementations/rands/seeding/rand_win.c
index 5a0815042d..63b523b729 100644
--- a/providers/implementations/rands/seeding/rand_win.c
+++ b/providers/implementations/rands/seeding/rand_win.c
@@ -70,7 +70,7 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool)
buffer = ossl_rand_pool_add_begin(pool, bytes_needed);
if (buffer != NULL) {
size_t bytes = 0;
- if (BCryptGenRandom(NULL, buffer, (ULONG)bytes_needed,
+ if (BCryptGenRandom(NULL, buffer, bytes_needed,
BCRYPT_USE_SYSTEM_PREFERRED_RNG)
== STATUS_SUCCESS)
bytes = bytes_needed;
diff --git a/ssl/rio/rio_notifier.c b/ssl/rio/rio_notifier.c
index 9d28614406..ab635aa7a0 100644
--- a/ssl/rio/rio_notifier.c
+++ b/ssl/rio/rio_notifier.c
@@ -31,21 +31,63 @@ static int set_cloexec(int fd)
#if defined(OPENSSL_SYS_WINDOWS)
static CRYPTO_ONCE ensure_wsa_startup_once = CRYPTO_ONCE_STATIC_INIT;
+static CRYPTO_RWLOCK *wsa_lock;
+static int wsa_started;
+static int wsa_ref;
+
+static void ossl_wsa_cleanup(void)
+{
+ if (wsa_started) {
+ wsa_started = 0;
+ WSACleanup();
+ }
+
+ CRYPTO_THREAD_lock_free(wsa_lock);
+ wsa_lock = NULL;
+}
DEFINE_RUN_ONCE_STATIC(do_wsa_startup)
{
WORD versionreq = 0x0202; /* Version 2.2 */
WSADATA wsadata;
- if (WSAStartup(versionreq, &wsadata) != 0)
+ wsa_lock = CRYPTO_THREAD_lock_new();
+ if (wsa_lock == NULL)
return 0;
+ if (WSAStartup(versionreq, &wsadata) != 0) {
+ CRYPTO_THREAD_lock_free(wsa_lock);
+ wsa_lock = NULL;
+ return 0;
+ }
+ wsa_started = 1;
+
return 1;
}
static ossl_inline int ensure_wsa_startup(void)
{
- return RUN_ONCE(&ensure_wsa_startup_once, do_wsa_startup);
+ int rv, unused;
+
+ rv = RUN_ONCE(&ensure_wsa_startup_once, do_wsa_startup);
+ if (rv != 0)
+ CRYPTO_atomic_add(&wsa_ref, 1, &unused, wsa_lock);
+
+ return rv;
+}
+
+static void wsa_done(void)
+{
+ int ref;
+
+ if (wsa_lock != NULL) {
+ CRYPTO_atomic_add(&wsa_ref, -1, &ref, wsa_lock);
+ if (ref == 0) {
+ ossl_wsa_cleanup();
+ ensure_wsa_startup_once = CRYPTO_ONCE_STATIC_INIT;
+ wsa_lock = NULL;
+ }
+ }
}
#endif
@@ -146,6 +188,8 @@ int ossl_rio_notifier_init(RIO_NOTIFIER *nfy)
if (!ensure_wsa_startup()) {
ERR_raise_data(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR,
"Cannot start Windows sockets");
+
+ wsa_done();
return 0;
}
#endif
@@ -332,6 +376,9 @@ void ossl_rio_notifier_cleanup(RIO_NOTIFIER *nfy)
BIO_closesocket(nfy->wfd);
BIO_closesocket(nfy->rfd);
nfy->rfd = nfy->wfd = -1;
+#if defined(OPENSSL_SYS_WINDOWS)
+ wsa_done();
+#endif
}
int ossl_rio_notifier_signal(RIO_NOTIFIER *nfy)
diff --git a/util/platform_symbols/windows-symbols.txt b/util/platform_symbols/windows-symbols.txt
index 7ae58a3f18..0f6cc11450 100644
--- a/util/platform_symbols/windows-symbols.txt
+++ b/util/platform_symbols/windows-symbols.txt
@@ -1,6 +1,5 @@
AcquireSRWLockExclusive
AcquireSRWLockShared
-BCryptGenRandom
CertCloseStore
CertFindCertificateInStore
CertFreeCertificateContext