From f26bc29cfec0be84c67cf74065cf8e5e78fd68b7 Mon Sep 17 00:00:00 2001 From: Jay Satiro Date: Sat, 16 Feb 2019 18:55:40 -0500 Subject: easy: fix win32 init to work without CURL_GLOBAL_WIN32 - Change the behavior of win32_init so that the required initialization procedures are not affected by CURL_GLOBAL_WIN32 flag. libcurl via curl_global_init supports initializing for win32 with an optional flag CURL_GLOBAL_WIN32, which if omitted was meant to stop Winsock initialization. It did so internally by skipping win32_init() when that flag was set. Since then win32_init() has been expanded to include required initialization routines that are separate from Winsock and therefore must be called in all cases. This commit fixes it so that CURL_GLOBAL_WIN32 only controls the optional win32 initialization (which is Winsock initialization, according to our doc). The only users affected by this change are those that don't pass CURL_GLOBAL_WIN32 to curl_global_init. For them this commit removes the risk of a potential crash. Ref: https://github.com/curl/curl/pull/3573 Fixes https://github.com/curl/curl/issues/3313 Closes https://github.com/curl/curl/pull/3575 --- lib/easy.c | 109 ++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 60 insertions(+), 49 deletions(-) diff --git a/lib/easy.c b/lib/easy.c index d2d4166d5..b1e264e8d 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -84,63 +84,76 @@ void Curl_version_init(void); -/* win32_cleanup() is for win32 socket cleanup functionality, the opposite - of win32_init() */ -static void win32_cleanup(void) +/* true globals -- for curl_global_init() and curl_global_cleanup() */ +static unsigned int initialized; +static long init_flags; + +/* + * win32 init and cleanup functions + */ +#ifdef WIN32 + +/* win32_cleanup() is the opposite of win32_init() */ +static void win32_cleanup() { -#ifdef USE_WINSOCK - WSACleanup(); -#endif #ifdef USE_WINDOWS_SSPI Curl_sspi_global_cleanup(); #endif + + if(init_flags & CURL_GLOBAL_WIN32) { +#ifdef USE_WINSOCK + WSACleanup(); +#endif + } } -#ifdef WIN32 LARGE_INTEGER Curl_freq; bool Curl_isVistaOrGreater; -#endif -/* win32_init() performs win32 socket initialization to properly setup the - stack to allow networking */ -static CURLcode win32_init(void) +/* win32_init() performs win32 global initialization */ +static CURLcode win32_init(long flags) { + /* 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. */ + if(flags & CURL_GLOBAL_WIN32) { #ifdef USE_WINSOCK - WORD wVersionRequested; - WSADATA wsaData; - int res; + WORD wVersionRequested; + WSADATA wsaData; + int res; #if defined(ENABLE_IPV6) && (USE_WINSOCK < 2) - Error IPV6_requires_winsock2 +#error IPV6_requires_winsock2 #endif - wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK); + wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK); - res = WSAStartup(wVersionRequested, &wsaData); + res = WSAStartup(wVersionRequested, &wsaData); - if(res != 0) - /* Tell the user that we couldn't find a usable */ - /* winsock.dll. */ - return CURLE_FAILED_INIT; + if(res != 0) + /* Tell the user that we couldn't find a usable */ + /* winsock.dll. */ + return CURLE_FAILED_INIT; - /* Confirm that the Windows Sockets DLL supports what we need.*/ - /* Note that if the DLL supports versions greater */ - /* than wVersionRequested, it will still return */ - /* wVersionRequested in wVersion. wHighVersion contains the */ - /* highest supported version. */ + /* Confirm that the Windows Sockets DLL supports what we need.*/ + /* Note that if the DLL supports versions greater */ + /* than wVersionRequested, it will still return */ + /* wVersionRequested in wVersion. wHighVersion contains the */ + /* highest supported version. */ - if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || - HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) { - /* Tell the user that we couldn't find a usable */ + if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || + HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) { + /* Tell the user that we couldn't find a usable */ - /* winsock.dll. */ - WSACleanup(); - return CURLE_FAILED_INIT; - } - /* The Windows Sockets DLL is acceptable. Proceed. */ -#elif defined(USE_LWIPSOCK) - lwip_init(); -#endif + /* winsock.dll. */ + WSACleanup(); + return CURLE_FAILED_INIT; + } + /* The Windows Sockets DLL is acceptable. Proceed. */ + #elif defined(USE_LWIPSOCK) + lwip_init(); + #endif + } /* CURL_GLOBAL_WIN32 */ #ifdef USE_WINDOWS_SSPI { @@ -150,7 +163,6 @@ static CURLcode win32_init(void) } #endif -#ifdef WIN32 if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT, VERSION_GREATER_THAN_EQUAL)) { Curl_isVistaOrGreater = TRUE; @@ -158,14 +170,11 @@ static CURLcode win32_init(void) } else Curl_isVistaOrGreater = FALSE; -#endif return CURLE_OK; } -/* true globals -- for curl_global_init() and curl_global_cleanup() */ -static unsigned int initialized; -static long init_flags; +#endif /* WIN32 */ /* * strdup (and other memory functions) is redefined in complicated @@ -239,11 +248,12 @@ static CURLcode global_init(long flags, bool memoryfuncs) return CURLE_FAILED_INIT; } - if(flags & CURL_GLOBAL_WIN32) - if(win32_init()) { - DEBUGF(fprintf(stderr, "Error: win32_init failed\n")); - return CURLE_FAILED_INIT; - } +#ifdef WIN32 + if(win32_init(flags)) { + DEBUGF(fprintf(stderr, "Error: win32_init failed\n")); + return CURLE_FAILED_INIT; + } +#endif #ifdef __AMIGA__ if(!Curl_amiga_init()) { @@ -347,8 +357,9 @@ void curl_global_cleanup(void) Curl_ssl_cleanup(); Curl_resolver_global_cleanup(); - if(init_flags & CURL_GLOBAL_WIN32) - win32_cleanup(); +#ifdef WIN32 + win32_cleanup(); +#endif Curl_amiga_cleanup(); -- cgit v1.2.1