diff --git a/expat/CMakeLists.txt b/expat/CMakeLists.txt index 4b743cdf..e2098e0e 100644 --- a/expat/CMakeLists.txt +++ b/expat/CMakeLists.txt @@ -175,7 +175,6 @@ if(WIN32) endif(WIN32) set(expat_SRCS - lib/loadlibrary.c lib/xmlparse.c lib/xmlrole.c lib/xmltok.c diff --git a/expat/Changes b/expat/Changes index e6b9044e..bee743cd 100644 --- a/expat/Changes +++ b/expat/Changes @@ -16,6 +16,9 @@ Release x.x.x xxx xxx xx xxxx #265 CMake: Fix linking with MinGW #239 #277 CMake: Add argument -DUSE_GETRANDOM=(ON|OFF|AUTO) #239 #277 CMake: Add argument -DUSE_SYS_GETRANDOM=(ON|OFF|AUTO) + #299 #302 Windows: Replace LoadLibrary hack to access + unofficial API function SystemFunction036 (RtlGenRandom) + by using official API function rand_s (needs WinXP+) #14 Drop an OpenVMS support leftover #235 #268 #270 Address compiler warnings #282 #283 .. @@ -24,6 +27,7 @@ Release x.x.x xxx xxx xx xxxx #24 #293 Mass-apply clang-format 9 (and ensure conformance during CI) Special thanks to: + David Loffredo Khajapasha Mohammed Kishore Kunche Marco Maggi diff --git a/expat/lib/Makefile.am b/expat/lib/Makefile.am index 534369e8..8cb451ed 100644 --- a/expat/lib/Makefile.am +++ b/expat/lib/Makefile.am @@ -40,7 +40,6 @@ libexpat_la_LDFLAGS = \ -version-info @LIBCURRENT@:@LIBREVISION@:@LIBAGE@ libexpat_la_SOURCES = \ - loadlibrary.c \ xmlparse.c \ xmltok.c \ xmlrole.c diff --git a/expat/lib/expat.vcxproj b/expat/lib/expat.vcxproj index 69cb2335..609c816f 100644 --- a/expat/lib/expat.vcxproj +++ b/expat/lib/expat.vcxproj @@ -148,7 +148,6 @@ - diff --git a/expat/lib/expat.vcxproj.filters b/expat/lib/expat.vcxproj.filters index 61c52b58..34aea26d 100644 --- a/expat/lib/expat.vcxproj.filters +++ b/expat/lib/expat.vcxproj.filters @@ -15,9 +15,6 @@ - - Source Files - Source Files diff --git a/expat/lib/expat_static.vcxproj b/expat/lib/expat_static.vcxproj index 825fc518..b09020c0 100644 --- a/expat/lib/expat_static.vcxproj +++ b/expat/lib/expat_static.vcxproj @@ -121,7 +121,6 @@ - diff --git a/expat/lib/expat_static.vcxproj.filters b/expat/lib/expat_static.vcxproj.filters index a2fe03e6..e6d9d80f 100644 --- a/expat/lib/expat_static.vcxproj.filters +++ b/expat/lib/expat_static.vcxproj.filters @@ -11,9 +11,6 @@ - - Source Files - Source Files diff --git a/expat/lib/expatw.vcxproj b/expat/lib/expatw.vcxproj index de8a0f8c..94783ac4 100644 --- a/expat/lib/expatw.vcxproj +++ b/expat/lib/expatw.vcxproj @@ -148,7 +148,6 @@ - diff --git a/expat/lib/expatw.vcxproj.filters b/expat/lib/expatw.vcxproj.filters index fb3909c9..dc6e9685 100644 --- a/expat/lib/expatw.vcxproj.filters +++ b/expat/lib/expatw.vcxproj.filters @@ -15,9 +15,6 @@ - - Source Files - Source Files diff --git a/expat/lib/expatw_static.vcxproj b/expat/lib/expatw_static.vcxproj index d195b1b1..0f7be78c 100644 --- a/expat/lib/expatw_static.vcxproj +++ b/expat/lib/expatw_static.vcxproj @@ -121,7 +121,6 @@ - diff --git a/expat/lib/expatw_static.vcxproj.filters b/expat/lib/expatw_static.vcxproj.filters index 724d9f8c..83a7c08c 100644 --- a/expat/lib/expatw_static.vcxproj.filters +++ b/expat/lib/expatw_static.vcxproj.filters @@ -11,9 +11,6 @@ - - Source Files - Source Files diff --git a/expat/lib/loadlibrary.c b/expat/lib/loadlibrary.c deleted file mode 100644 index 6c0ec892..00000000 --- a/expat/lib/loadlibrary.c +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2016 - 2017, Steve Holme, . - * Copyright (C) 2017, Expat development team - * - * All rights reserved. - * Licensed under the MIT license: - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH - * THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder shall - * not be used in advertising or otherwise to promote the sale, use or other - * dealings in this Software without prior written authorization of the - * copyright holder. - * - ***************************************************************************/ - -#if defined(_WIN32) - -# include -# include - -HMODULE _Expat_LoadLibrary(LPCTSTR filename); - -# if ! defined(LOAD_WITH_ALTERED_SEARCH_PATH) -# define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 -# endif - -# if ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32) -# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 -# endif - -/* We use our own typedef here since some headers might lack these */ -typedef HMODULE(APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD); - -/* See function definitions in winbase.h */ -# ifdef UNICODE -# ifdef _WIN32_WCE -# define LOADLIBARYEX L"LoadLibraryExW" -# else -# define LOADLIBARYEX "LoadLibraryExW" -# endif -# else -# define LOADLIBARYEX "LoadLibraryExA" -# endif - -/* - * _Expat_LoadLibrary() - * - * This is used to dynamically load DLLs using the most secure method available - * for the version of Windows that we are running on. - * - * Parameters: - * - * filename [in] - The filename or full path of the DLL to load. If only the - * filename is passed then the DLL will be loaded from the - * Windows system directory. - * - * Returns the handle of the module on success; otherwise NULL. - */ -HMODULE -_Expat_LoadLibrary(LPCTSTR filename) { - HMODULE hModule = NULL; - LOADLIBRARYEX_FN pLoadLibraryEx = NULL; - - /* Get a handle to kernel32 so we can access it's functions at runtime */ - HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32")); - if (! hKernel32) - return NULL; /* LCOV_EXCL_LINE */ - - /* Attempt to find LoadLibraryEx() which is only available on Windows 2000 - and above */ - pLoadLibraryEx = (LOADLIBRARYEX_FN)GetProcAddress(hKernel32, LOADLIBARYEX); - - /* Detect if there's already a path in the filename and load the library if - there is. Note: Both back slashes and forward slashes have been supported - since the earlier days of DOS at an API level although they are not - supported by command prompt */ - if (_tcspbrk(filename, TEXT("\\/"))) { - /** !checksrc! disable BANNEDFUNC 1 **/ - hModule = pLoadLibraryEx ? pLoadLibraryEx(filename, NULL, - LOAD_WITH_ALTERED_SEARCH_PATH) - : LoadLibrary(filename); - } - /* Detect if KB2533623 is installed, as LOAD_LIBARY_SEARCH_SYSTEM32 is only - supported on Windows Vista, Windows Server 2008, Windows 7 and Windows - Server 2008 R2 with this patch or natively on Windows 8 and above */ - else if (pLoadLibraryEx && GetProcAddress(hKernel32, "AddDllDirectory")) { - /* Load the DLL from the Windows system directory */ - hModule = pLoadLibraryEx(filename, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); - } else { - /* Attempt to get the Windows system path */ - UINT systemdirlen = GetSystemDirectory(NULL, 0); - if (systemdirlen) { - /* Allocate space for the full DLL path (Room for the null terminator - is included in systemdirlen) */ - size_t filenamelen = _tcslen(filename); - TCHAR *path = malloc(sizeof(TCHAR) * (systemdirlen + 1 + filenamelen)); - if (path && GetSystemDirectory(path, systemdirlen)) { - /* Calculate the full DLL path */ - _tcscpy(path + _tcslen(path), TEXT("\\")); - _tcscpy(path + _tcslen(path), filename); - - /* Load the DLL from the Windows system directory */ - /** !checksrc! disable BANNEDFUNC 1 **/ - hModule = pLoadLibraryEx ? pLoadLibraryEx(path, NULL, - LOAD_WITH_ALTERED_SEARCH_PATH) - : LoadLibrary(path); - } - free(path); - } - } - - return hModule; -} - -#else /* defined(_WIN32) */ - -/* ISO C requires a translation unit to contain at least one declaration - [-Wempty-translation-unit] */ -typedef int _TRANSLATION_UNIT_LOAD_LIBRARY_C_NOT_EMTPY; - -#endif /* defined(_WIN32) */ diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c index e89a2afd..aaa564f4 100644 --- a/expat/lib/xmlparse.c +++ b/expat/lib/xmlparse.c @@ -34,12 +34,17 @@ # define _GNU_SOURCE 1 /* syscall prototype */ #endif +#ifdef _WIN32 +/* force stdlib to define rand_s() */ +# define _CRT_RAND_S +#endif + #include #include /* memset(), memcpy() */ #include #include /* UINT_MAX */ #include /* fprintf */ -#include /* getenv */ +#include /* getenv, rand_s */ #ifdef _WIN32 # define getpid GetCurrentProcessId @@ -99,7 +104,7 @@ * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ * Linux / BSD / macOS (/dev/urandom): XML_DEV_URANDOM \ - * Windows (RtlGenRandom): _WIN32. \ + * Windows (rand_s): _WIN32. \ \ If insist on not using any of these, bypass this error by defining \ XML_POOR_ENTROPY; you have been warned. \ @@ -729,33 +734,28 @@ writeRandomBytes_arc4random(void *target, size_t count) { #ifdef _WIN32 -typedef BOOLEAN(APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG); -HMODULE _Expat_LoadLibrary(LPCTSTR filename); /* see loadlibrary.c */ - -/* Obtain entropy on Windows XP / Windows Server 2003 and later. - * Hint on RtlGenRandom and the following article from libsodium. - * - * Michael Howard: Cryptographically Secure Random number on Windows without - * using CryptoAPI - * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/ +/* Obtain entropy on Windows using the rand_s() function which + * generates cryptographically secure random numbers. Internally it + * uses RtlGenRandom API which is present in Windows XP and later. */ static int -writeRandomBytes_RtlGenRandom(void *target, size_t count) { - int success = 0; /* full count bytes written? */ - const HMODULE advapi32 = _Expat_LoadLibrary(TEXT("ADVAPI32.DLL")); +writeRandomBytes_rand_s(void *target, size_t count) { + size_t bytesWrittenTotal = 0; - if (advapi32) { - const RTLGENRANDOM_FUNC RtlGenRandom - = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036"); - if (RtlGenRandom) { - if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) { - success = 1; - } + while (bytesWrittenTotal < count) { + unsigned int random32 = 0; + size_t i = 0; + + if (rand_s(&random32)) + return 0; /* failure */ + + for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); + i++, bytesWrittenTotal++) { + const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); + ((uint8_t *)target)[bytesWrittenTotal] = random8; } - FreeLibrary(advapi32); } - - return success; + return 1; /* success */ } #endif /* _WIN32 */ @@ -812,8 +812,8 @@ generate_hash_secret_salt(XML_Parser parser) { #else /* Try high quality providers first .. */ # ifdef _WIN32 - if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) { - return ENTROPY_DEBUG("RtlGenRandom", entropy); + if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) { + return ENTROPY_DEBUG("rand_s", entropy); } # elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) {