asyn-thread: stop using GetAddrInfoExW on Windows

- For the threaded resolver backend on Windows, revert back to
  exclusively use the threaded resolver with libcurl-owned threading
  instead of GetAddrInfoExW with Windows-owned threading.

Winsock (the Windows sockets library) has a bug where it does not wait
for all of the name resolver threads it is managing to terminate before
returning from WSACleanup. The threads continue to run and may cause a
crash.

This commit is effectively a revert of several commits that encompass
all GetAddrInfoExW code in libcurl. A manual review of merge conflicts
was used to resolve minor changes that had modified the code for
aesthetic or build reasons in other commits.

Prior to this change if libcurl was built with the threaded resolver
backend for Windows, and Windows 8 or later was the operating system at
runtime, and the caller was not impersonating another user, then libcurl
would use GetAddrInfoExW to handle asynchronous name lookups.

GetAddrInfoExW support was added in a6bbc87f, which preceded 8.6.0, and
prior to that the threaded resolver backend used libcurl-owned threading
exclusively on Windows.

Reported-by: Ionuț-Francisc Oancea
Reported-by: Razvan Pricope

Ref: https://developercommunity.visualstudio.com/t/ASAN:-heap-use-after-free-in-NdrFullPoin/10654169

Fixes https://github.com/curl/curl/issues/13509#issuecomment-2225338110
Closes https://github.com/curl/curl/pull/14794

---

Revert "asyn-thread: avoid using GetAddrInfoExW with impersonation"

This reverts commit 0caadc1f24.

Conflicts:
	lib/system_win32.c

--

Revert "asyn-thread: fix curl_global_cleanup crash in Windows"

This reverts commit 428579f5d1.

--

Revert "system_win32: fix a function pointer assignment warning"

This reverts commit 26f002e02e.

--

Revert "asyn-thread: use GetAddrInfoExW on >= Windows 8"

This reverts commit a6bbc87f9e.

Conflicts:
	lib/asyn-thread.c
	lib/system_win32.c

--
This commit is contained in:
Jay Satiro 2024-09-05 02:18:25 -04:00
parent 24606191f8
commit eb8ad66f6c
3 changed files with 3 additions and 328 deletions

View file

@ -38,23 +38,16 @@
LARGE_INTEGER Curl_freq;
bool Curl_isVistaOrGreater;
bool Curl_isWindows8OrGreater;
/* Handle of iphlpapp.dll */
static HMODULE s_hIpHlpApiDll = NULL;
/* Function pointers */
/* Pointer to the if_nametoindex function */
IF_NAMETOINDEX_FN Curl_if_nametoindex = NULL;
FREEADDRINFOEXW_FN Curl_FreeAddrInfoExW = NULL;
GETADDRINFOEXCANCEL_FN Curl_GetAddrInfoExCancel = NULL;
GETADDRINFOEXW_FN Curl_GetAddrInfoExW = NULL;
/* Curl_win32_init() performs Win32 global initialization */
CURLcode Curl_win32_init(long flags)
{
#ifdef USE_WINSOCK
HMODULE ws2_32Dll;
#endif
/* CURL_GLOBAL_WIN32 controls the *optional* part of the initialization which
is just for Winsock at the moment. Any required Win32 initialization
should take place after this block. */
@ -111,22 +104,6 @@ CURLcode Curl_win32_init(long flags)
Curl_if_nametoindex = pIfNameToIndex;
}
#ifdef USE_WINSOCK
#ifdef CURL_WINDOWS_APP
ws2_32Dll = Curl_load_library(TEXT("ws2_32.dll"));
#else
ws2_32Dll = GetModuleHandleA("ws2_32");
#endif
if(ws2_32Dll) {
Curl_FreeAddrInfoExW = CURLX_FUNCTION_CAST(FREEADDRINFOEXW_FN,
GetProcAddress(ws2_32Dll, "FreeAddrInfoExW"));
Curl_GetAddrInfoExCancel = CURLX_FUNCTION_CAST(GETADDRINFOEXCANCEL_FN,
GetProcAddress(ws2_32Dll, "GetAddrInfoExCancel"));
Curl_GetAddrInfoExW = CURLX_FUNCTION_CAST(GETADDRINFOEXW_FN,
GetProcAddress(ws2_32Dll, "GetAddrInfoExW"));
}
#endif
/* curlx_verify_windows_version must be called during init at least once
because it has its own initialization routine. */
if(curlx_verify_windows_version(6, 0, 0, PLATFORM_WINNT,
@ -136,13 +113,6 @@ CURLcode Curl_win32_init(long flags)
else
Curl_isVistaOrGreater = FALSE;
if(curlx_verify_windows_version(6, 2, 0, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
Curl_isWindows8OrGreater = TRUE;
}
else
Curl_isWindows8OrGreater = FALSE;
QueryPerformanceFrequency(&Curl_freq);
return CURLE_OK;
}
@ -150,9 +120,6 @@ CURLcode Curl_win32_init(long flags)
/* Curl_win32_cleanup() is the opposite of Curl_win32_init() */
void Curl_win32_cleanup(long init_flags)
{
Curl_FreeAddrInfoExW = NULL;
Curl_GetAddrInfoExCancel = NULL;
Curl_GetAddrInfoExW = NULL;
if(s_hIpHlpApiDll) {
FreeLibrary(s_hIpHlpApiDll);
s_hIpHlpApiDll = NULL;
@ -271,16 +238,4 @@ HMODULE Curl_load_library(LPCTSTR filename)
#endif
}
bool Curl_win32_impersonating(void)
{
#ifndef CURL_WINDOWS_APP
HANDLE token = NULL;
if(OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token)) {
CloseHandle(token);
return TRUE;
}
#endif
return FALSE;
}
#endif /* _WIN32 */