From: Tomas Mraz Date: Tue, 16 Jun 2026 10:45:19 +0000 (+0200) Subject: Revert "convert CRYPTO_THREAD_run_once to use InitOnceExecuteOnce api" X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f3f163243a4fd6f5caea7bdb5ecc655f8c600cbb;p=thirdparty%2Fopenssl.git Revert "convert CRYPTO_THREAD_run_once to use InitOnceExecuteOnce api" This reverts commit d053fe41a4add4e55dc5633e8aef6602a6a4b90b. Reviewed-by: Eugene Syromiatnikov Reviewed-by: Nikola Pajkovsky 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 d803b7221d9..4fedf24e90c 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 f0de2f363ca..3ea75209cf5 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 #include diff --git a/include/openssl/crypto.h.in b/include/openssl/crypto.h.in index 071b11b3bc2..a9ade25b155 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 698f2da26bf..bacc161bd6b 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 5a0815042dc..63b523b729f 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 9d286144068..ab635aa7a0b 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 7ae58a3f182..0f6cc11450c 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