mirror of
https://github.com/curl/curl.git
synced 2026-04-11 12:01:42 +08:00
windows: determine RtlVerifyVersionInfo address on global init
Instead of the first internal call to `curlx_verify_windows_version()`.
To avoid the chance of a race, potentially resulting in initializing
this address twice. AFAICT it could not cause an issue before this
patch.
Reported by Codex Security
Follow-up to b17ef873ae #18009
Closes #20853
This commit is contained in:
parent
ccba492024
commit
6a6826469d
@ -27,6 +27,7 @@
|
||||
|
||||
#include "curlx/version_win32.h"
|
||||
|
||||
#ifndef CURL_WINDOWS_UWP
|
||||
/* This Unicode version struct works for VerifyVersionInfoW (OSVERSIONINFOEXW)
|
||||
and RtlVerifyVersionInfo (RTLOSVERSIONINFOEXW) */
|
||||
struct OUR_OSVERSIONINFOEXW {
|
||||
@ -43,6 +44,24 @@ struct OUR_OSVERSIONINFOEXW {
|
||||
UCHAR wReserved;
|
||||
};
|
||||
|
||||
typedef LONG (APIENTRY *RTLVERIFYVERSIONINFO_FN)
|
||||
(struct OUR_OSVERSIONINFOEXW *, ULONG, ULONGLONG);
|
||||
static RTLVERIFYVERSIONINFO_FN s_pRtlVerifyVersionInfo;
|
||||
|
||||
void curlx_verify_windows_init(void)
|
||||
{
|
||||
#if defined(__clang__) && __clang_major__ >= 16
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wcast-function-type-strict"
|
||||
#endif
|
||||
s_pRtlVerifyVersionInfo = CURLX_FUNCTION_CAST(RTLVERIFYVERSIONINFO_FN,
|
||||
GetProcAddress(GetModuleHandle(TEXT("ntdll")), "RtlVerifyVersionInfo"));
|
||||
#if defined(__clang__) && __clang_major__ >= 16
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
#endif /* !CURL_WINDOWS_UWP */
|
||||
|
||||
/*
|
||||
* curlx_verify_windows_version()
|
||||
*
|
||||
@ -115,24 +134,6 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
|
||||
DWORD dwTypeMask = VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR;
|
||||
|
||||
typedef LONG (APIENTRY *RTLVERIFYVERSIONINFO_FN)
|
||||
(struct OUR_OSVERSIONINFOEXW *, ULONG, ULONGLONG);
|
||||
static RTLVERIFYVERSIONINFO_FN pRtlVerifyVersionInfo;
|
||||
static bool onetime = TRUE; /* safe because first call is during init */
|
||||
|
||||
if(onetime) {
|
||||
#if defined(__clang__) && __clang_major__ >= 16
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wcast-function-type-strict"
|
||||
#endif
|
||||
pRtlVerifyVersionInfo = CURLX_FUNCTION_CAST(RTLVERIFYVERSIONINFO_FN,
|
||||
GetProcAddress(GetModuleHandle(TEXT("ntdll")), "RtlVerifyVersionInfo"));
|
||||
#if defined(__clang__) && __clang_major__ >= 16
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
onetime = FALSE;
|
||||
}
|
||||
|
||||
switch(condition) {
|
||||
case VERSION_LESS_THAN:
|
||||
majorCondition = VER_LESS;
|
||||
@ -203,8 +204,8 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
|
||||
the real version always, so we use the Rtl variant of the function when
|
||||
possible. Note though the function signatures have underlying fundamental
|
||||
types that are the same, the return values are different. */
|
||||
if(pRtlVerifyVersionInfo)
|
||||
matched = !pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
|
||||
if(s_pRtlVerifyVersionInfo)
|
||||
matched = !s_pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
|
||||
else
|
||||
matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver, dwTypeMask, cm);
|
||||
|
||||
@ -222,8 +223,8 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
|
||||
|
||||
cm = VerSetConditionMask(0, VER_BUILDNUMBER, buildCondition);
|
||||
dwTypeMask = VER_BUILDNUMBER;
|
||||
if(pRtlVerifyVersionInfo)
|
||||
matched = !pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
|
||||
if(s_pRtlVerifyVersionInfo)
|
||||
matched = !s_pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
|
||||
else
|
||||
matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver,
|
||||
dwTypeMask, cm);
|
||||
|
||||
@ -43,6 +43,11 @@ typedef enum {
|
||||
PLATFORM_WINNT
|
||||
} PlatformIdentifier;
|
||||
|
||||
#ifdef CURL_WINDOWS_UWP
|
||||
#define curlx_verify_windows_init() Curl_nop_stmt
|
||||
#else
|
||||
void curlx_verify_windows_init(void);
|
||||
#endif
|
||||
/* This is used to verify if we are running on a specific Windows version */
|
||||
bool curlx_verify_windows_version(const unsigned int majorVersion,
|
||||
const unsigned int minorVersion,
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "system_win32.h"
|
||||
#include "curl_sspi.h"
|
||||
#include "curlx/timeval.h"
|
||||
#include "curlx/version_win32.h" /* for curlx_verify_windows_init() */
|
||||
|
||||
/* Curl_win32_init() performs Win32 global initialization */
|
||||
CURLcode Curl_win32_init(long flags)
|
||||
@ -77,6 +78,7 @@ CURLcode Curl_win32_init(long flags)
|
||||
}
|
||||
#endif
|
||||
|
||||
curlx_verify_windows_init();
|
||||
curlx_now_init();
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -901,6 +901,7 @@ curl_socket_t win32_stdin_read_thread(void)
|
||||
|
||||
CURLcode win32_init(void)
|
||||
{
|
||||
curlx_verify_windows_init();
|
||||
curlx_now_init();
|
||||
#ifndef CURL_WINDOWS_UWP
|
||||
init_terminal();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user