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"
|
#include "curlx/version_win32.h"
|
||||||
|
|
||||||
|
#ifndef CURL_WINDOWS_UWP
|
||||||
/* This Unicode version struct works for VerifyVersionInfoW (OSVERSIONINFOEXW)
|
/* This Unicode version struct works for VerifyVersionInfoW (OSVERSIONINFOEXW)
|
||||||
and RtlVerifyVersionInfo (RTLOSVERSIONINFOEXW) */
|
and RtlVerifyVersionInfo (RTLOSVERSIONINFOEXW) */
|
||||||
struct OUR_OSVERSIONINFOEXW {
|
struct OUR_OSVERSIONINFOEXW {
|
||||||
@ -43,6 +44,24 @@ struct OUR_OSVERSIONINFOEXW {
|
|||||||
UCHAR wReserved;
|
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()
|
* curlx_verify_windows_version()
|
||||||
*
|
*
|
||||||
@ -115,24 +134,6 @@ bool curlx_verify_windows_version(const unsigned int majorVersion,
|
|||||||
DWORD dwTypeMask = VER_MAJORVERSION | VER_MINORVERSION |
|
DWORD dwTypeMask = VER_MAJORVERSION | VER_MINORVERSION |
|
||||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR;
|
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) {
|
switch(condition) {
|
||||||
case VERSION_LESS_THAN:
|
case VERSION_LESS_THAN:
|
||||||
majorCondition = VER_LESS;
|
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
|
the real version always, so we use the Rtl variant of the function when
|
||||||
possible. Note though the function signatures have underlying fundamental
|
possible. Note though the function signatures have underlying fundamental
|
||||||
types that are the same, the return values are different. */
|
types that are the same, the return values are different. */
|
||||||
if(pRtlVerifyVersionInfo)
|
if(s_pRtlVerifyVersionInfo)
|
||||||
matched = !pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
|
matched = !s_pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
|
||||||
else
|
else
|
||||||
matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver, dwTypeMask, cm);
|
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);
|
cm = VerSetConditionMask(0, VER_BUILDNUMBER, buildCondition);
|
||||||
dwTypeMask = VER_BUILDNUMBER;
|
dwTypeMask = VER_BUILDNUMBER;
|
||||||
if(pRtlVerifyVersionInfo)
|
if(s_pRtlVerifyVersionInfo)
|
||||||
matched = !pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
|
matched = !s_pRtlVerifyVersionInfo(&osver, dwTypeMask, cm);
|
||||||
else
|
else
|
||||||
matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver,
|
matched = !!VerifyVersionInfoW((OSVERSIONINFOEXW *)&osver,
|
||||||
dwTypeMask, cm);
|
dwTypeMask, cm);
|
||||||
|
|||||||
@ -43,6 +43,11 @@ typedef enum {
|
|||||||
PLATFORM_WINNT
|
PLATFORM_WINNT
|
||||||
} PlatformIdentifier;
|
} 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 */
|
/* This is used to verify if we are running on a specific Windows version */
|
||||||
bool curlx_verify_windows_version(const unsigned int majorVersion,
|
bool curlx_verify_windows_version(const unsigned int majorVersion,
|
||||||
const unsigned int minorVersion,
|
const unsigned int minorVersion,
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
#include "system_win32.h"
|
#include "system_win32.h"
|
||||||
#include "curl_sspi.h"
|
#include "curl_sspi.h"
|
||||||
#include "curlx/timeval.h"
|
#include "curlx/timeval.h"
|
||||||
|
#include "curlx/version_win32.h" /* for curlx_verify_windows_init() */
|
||||||
|
|
||||||
/* Curl_win32_init() performs Win32 global initialization */
|
/* Curl_win32_init() performs Win32 global initialization */
|
||||||
CURLcode Curl_win32_init(long flags)
|
CURLcode Curl_win32_init(long flags)
|
||||||
@ -77,6 +78,7 @@ CURLcode Curl_win32_init(long flags)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
curlx_verify_windows_init();
|
||||||
curlx_now_init();
|
curlx_now_init();
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -901,6 +901,7 @@ curl_socket_t win32_stdin_read_thread(void)
|
|||||||
|
|
||||||
CURLcode win32_init(void)
|
CURLcode win32_init(void)
|
||||||
{
|
{
|
||||||
|
curlx_verify_windows_init();
|
||||||
curlx_now_init();
|
curlx_now_init();
|
||||||
#ifndef CURL_WINDOWS_UWP
|
#ifndef CURL_WINDOWS_UWP
|
||||||
init_terminal();
|
init_terminal();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user