Skip to content

[Backport] Windows: Restrict path for dynamic library loading #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: hp
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libusb/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ WINCE_USB_SRC = os/wince_usb.c os/wince_usb.h
EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(OPENBSD_USB_SRC) \
$(NETBSD_USB_SRC) $(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
$(POSIX_POLL_SRC) \
os/threads_posix.c os/threads_windows.c \
os/threads_posix.c os/threads_windows.c os/windows_common.c \
os/linux_udev.c os/linux_netlink.c

if OS_LINUX
Expand Down
59 changes: 59 additions & 0 deletions libusb/os/windows_common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* windows backend for libusb 1.0
* Copyright © 2009-2012 Pete Batard <[email protected]>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
* HID Reports IOCTLs inspired from HIDAPI by Alan Ott, Signal 11 Software
* Hash table functions adapted from glibc, by Ulrich Drepper et al.
* Major code testing contribution by Xiaofan Chen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <config.h>

#include <stdio.h>

#include "libusbi.h"
#include "windows_common.h"

/*
* Dynamically loads a DLL from the Windows system directory. Unlike the
* LoadLibraryA() function, this function will not search through any
* directories to try and find the library.
*/
HMODULE load_system_library(struct libusb_context *ctx, const char *name)
{
char library_path[MAX_PATH];
char *filename_start;
UINT length;

length = GetSystemDirectoryA(library_path, sizeof(library_path));
if ((length == 0) || (length >= (UINT)sizeof(library_path))) {
usbi_err(ctx, "program assertion failed - could not get system directory");
return NULL;
}

filename_start = library_path + length;
// Append '\' + name + ".dll" + NUL
length += 1 + strlen(name) + 4 + 1;
if (length >= (UINT)sizeof(library_path)) {
usbi_err(ctx, "program assertion failed - library path buffer overflow");
return NULL;
}

sprintf(filename_start, "\\%s.dll", name);
return LoadLibraryA(library_path);
}
48 changes: 24 additions & 24 deletions libusb/os/windows_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,36 +73,36 @@
#ifndef _WIN32_WCE
#define DLL_STRINGIFY(dll) #dll
#define DLL_GET_MODULE_HANDLE(dll) GetModuleHandleA(DLL_STRINGIFY(dll))
#define DLL_LOAD_LIBRARY(dll) LoadLibraryA(DLL_STRINGIFY(dll))
#else
#define DLL_STRINGIFY(dll) L#dll
#define DLL_GET_MODULE_HANDLE(dll) GetModuleHandle(DLL_STRINGIFY(dll))
#define DLL_LOAD_LIBRARY(dll) LoadLibrary(DLL_STRINGIFY(dll))
#endif

#define DLL_LOAD_PREFIXNAME(dll, prefixname, name, ret_on_failure) \
do { \
HMODULE h = DLL_GET_MODULE_HANDLE(dll); \
if (!h) \
h = DLL_LOAD_LIBRARY(dll); \
if (!h) { \
if (ret_on_failure) { return LIBUSB_ERROR_NOT_FOUND; } \
else { break; } \
} \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name)); \
if (prefixname) break; \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \
if (prefixname) break; \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \
if (prefixname) break; \
if(ret_on_failure) \
return LIBUSB_ERROR_NOT_FOUND; \
#define DLL_LOAD_PREFIXNAME(ctx, dll, prefixname, name, ret_on_failure) \
do { \
HMODULE h = DLL_GET_MODULE_HANDLE(dll); \
if (!h) \
h = load_system_library(ctx, DLL_STRINGIFY(dll)); \
if (!h) { \
if (ret_on_failure) { return LIBUSB_ERROR_NOT_FOUND; } \
else { break; } \
} \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name)); \
if (prefixname) break; \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \
if (prefixname) break; \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \
if (prefixname) break; \
if(ret_on_failure) \
return LIBUSB_ERROR_NOT_FOUND; \
} while(0)

#define DLL_DECLARE(api, ret, name, args) DLL_DECLARE_PREFIXNAME(api, ret, name, name, args)
#define DLL_LOAD(dll, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, name, name, ret_on_failure)
#define DLL_LOAD(ctx, dll, name, ret_on_failure) DLL_LOAD_PREFIXNAME(ctx, dll, name, name, ret_on_failure)
#define DLL_DECLARE_PREFIXED(api, ret, prefix, name, args) DLL_DECLARE_PREFIXNAME(api, ret, prefix##name, name, args)
#define DLL_LOAD_PREFIXED(dll, prefix, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, prefix##name, name, ret_on_failure)
#define DLL_LOAD_PREFIXED(ctx, dll, prefix, name, ret_on_failure) DLL_LOAD_PREFIXNAME(ctx, dll, prefix##name, name, ret_on_failure)

HMODULE load_system_library(struct libusb_context *ctx, const char *name);
90 changes: 43 additions & 47 deletions libusb/os/windows_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,31 +306,31 @@ static char *sanitize_path(const char *path)
/*
* Cfgmgr32, User32, OLE32 and SetupAPI DLL functions
*/
static int init_dlls(void)
static int init_dlls(struct libusb_context *ctx)
{
DLL_LOAD(Cfgmgr32.dll, CM_Get_Parent, TRUE);
DLL_LOAD(Cfgmgr32.dll, CM_Get_Child, TRUE);
DLL_LOAD(Cfgmgr32.dll, CM_Get_Sibling, TRUE);
DLL_LOAD(Cfgmgr32.dll, CM_Get_Device_IDA, TRUE);
DLL_LOAD(Cfgmgr32.dll, CM_Get_Device_ID_Size, TRUE);
DLL_LOAD(ctx, Cfgmgr32.dll, CM_Get_Parent, TRUE);
DLL_LOAD(ctx, Cfgmgr32.dll, CM_Get_Child, TRUE);
DLL_LOAD(ctx, Cfgmgr32.dll, CM_Get_Sibling, TRUE);
DLL_LOAD(ctx, Cfgmgr32.dll, CM_Get_Device_IDA, TRUE);
DLL_LOAD(ctx, Cfgmgr32.dll, CM_Get_Device_ID_Size, TRUE);

// Prefixed to avoid conflict with header files
DLL_LOAD_PREFIXED(OLE32.dll, p, CLSIDFromString, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetClassDevsA, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetClassDevsExA, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInfo, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiEnumDeviceInterfaces, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceInterfaceDetailA, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiDestroyDeviceInfoList, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDevRegKey, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiGetDeviceRegistryPropertyA, TRUE);
DLL_LOAD_PREFIXED(SetupAPI.dll, p, SetupDiOpenDeviceInterfaceRegKey, TRUE);
DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegQueryValueExW, TRUE);
DLL_LOAD_PREFIXED(AdvAPI32.dll, p, RegCloseKey, TRUE);
DLL_LOAD_PREFIXED(User32.dll, p, RegisterClassExA, TRUE);
DLL_LOAD_PREFIXED(User32.dll, p, RegisterDeviceNotificationA, TRUE);
DLL_LOAD_PREFIXED(User32.dll, p, UnregisterDeviceNotification, TRUE);
DLL_LOAD_PREFIXED(User32.dll, p, UnregisterClassA, TRUE);
DLL_LOAD_PREFIXED(ctx, OLE32.dll, p, CLSIDFromString, TRUE);
DLL_LOAD_PREFIXED(ctx, SetupAPI.dll, p, SetupDiGetClassDevsA, TRUE);
DLL_LOAD_PREFIXED(ctx, SetupAPI.dll, p, SetupDiGetClassDevsExA, TRUE);
DLL_LOAD_PREFIXED(ctx, SetupAPI.dll, p, SetupDiEnumDeviceInfo, TRUE);
DLL_LOAD_PREFIXED(ctx, SetupAPI.dll, p, SetupDiEnumDeviceInterfaces, TRUE);
DLL_LOAD_PREFIXED(ctx, SetupAPI.dll, p, SetupDiGetDeviceInterfaceDetailA, TRUE);
DLL_LOAD_PREFIXED(ctx, SetupAPI.dll, p, SetupDiDestroyDeviceInfoList, TRUE);
DLL_LOAD_PREFIXED(ctx, SetupAPI.dll, p, SetupDiOpenDevRegKey, TRUE);
DLL_LOAD_PREFIXED(ctx, SetupAPI.dll, p, SetupDiGetDeviceRegistryPropertyA, TRUE);
DLL_LOAD_PREFIXED(ctx, SetupAPI.dll, p, SetupDiOpenDeviceInterfaceRegKey, TRUE);
DLL_LOAD_PREFIXED(ctx, AdvAPI32.dll, p, RegQueryValueExW, TRUE);
DLL_LOAD_PREFIXED(ctx, AdvAPI32.dll, p, RegCloseKey, TRUE);
DLL_LOAD_PREFIXED(ctx, User32.dll, p, RegisterClassExA, TRUE);
DLL_LOAD_PREFIXED(ctx, User32.dll, p, RegisterDeviceNotificationA, TRUE);
DLL_LOAD_PREFIXED(ctx, User32.dll, p, UnregisterDeviceNotification, TRUE);
DLL_LOAD_PREFIXED(ctx, User32.dll, p, UnregisterClassA, TRUE);

return LIBUSB_SUCCESS;
}
Expand Down Expand Up @@ -991,10 +991,7 @@ static BOOL is_x64(void)
BOOL ret = FALSE;
// Detect if we're running a 32 or 64 bit system
if (sizeof(uintptr_t) < 8) {
DLL_LOAD_PREFIXED(Kernel32.dll, p, IsWow64Process, FALSE);
if (pIsWow64Process != NULL) {
(*pIsWow64Process)(GetCurrentProcess(), &ret);
}
IsWow64Process(GetCurrentProcess(), &ret);
} else {
ret = TRUE;
}
Expand Down Expand Up @@ -1703,7 +1700,7 @@ static int windows_init(struct libusb_context *ctx)
// NB: concurrent usage supposes that init calls are equally balanced with
// exit calls. If init is called more than exit, we will not exit properly
if ( ++concurrent_usage == 0 ) { // First init?
get_windows_version();
get_windows_version(ctx);
usbi_dbg(windows_version_str);
if (windows_version == WINDOWS_UNSUPPORTED) {
usbi_err(ctx, "This version of Windows is NOT supported");
Expand All @@ -1722,7 +1719,7 @@ static int windows_init(struct libusb_context *ctx)
}

// Load DLL imports
if (init_dlls() != LIBUSB_SUCCESS) {
if (init_dlls(ctx) != LIBUSB_SUCCESS) {
usbi_err(ctx, "could not resolve DLL functions");
return LIBUSB_ERROR_NOT_FOUND;
}
Expand Down Expand Up @@ -3430,7 +3427,6 @@ const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = {
},
};


/*
* WinUSB-like (WinUSB, libusb0/libusbK through libusbk DLL) API functions
*/
Expand All @@ -3448,13 +3444,13 @@ static int winusbx_init(int sub_api, struct libusb_context *ctx)

h = GetModuleHandleA("libusbK");
if (h == NULL) {
h = LoadLibraryA("libusbK");
h = load_system_library(ctx, "libusbK");
}
if (h == NULL) {
usbi_info(ctx, "libusbK DLL is not available, will use native WinUSB");
h = GetModuleHandleA("WinUSB");
if (h == NULL) {
h = LoadLibraryA("WinUSB");
h = load_system_library(ctx, "WinUSB");
} if (h == NULL) {
usbi_warn(ctx, "WinUSB DLL is not available either,\n"
"you will not be able to access devices outside of enumeration");
Expand Down Expand Up @@ -4549,22 +4545,22 @@ static int _hid_class_request(struct hid_device_priv *dev, HANDLE hid_handle, in
*/
static int hid_init(int sub_api, struct libusb_context *ctx)
{
DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE);
DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE);
DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE);
DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE);
DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE);
DLL_LOAD(hid.dll, HidD_GetProductString, TRUE);
DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE);
DLL_LOAD(hid.dll, HidP_GetCaps, TRUE);
DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE);
DLL_LOAD(hid.dll, HidD_SetFeature, TRUE);
DLL_LOAD(hid.dll, HidD_GetFeature, TRUE);
DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE);
DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE);
DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE);
DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE);
DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE);
DLL_LOAD(ctx, hid.dll, HidD_GetAttributes, TRUE);
DLL_LOAD(ctx, hid.dll, HidD_GetHidGuid, TRUE);
DLL_LOAD(ctx, hid.dll, HidD_GetPreparsedData, TRUE);
DLL_LOAD(ctx, hid.dll, HidD_FreePreparsedData, TRUE);
DLL_LOAD(ctx, hid.dll, HidD_GetManufacturerString, TRUE);
DLL_LOAD(ctx, hid.dll, HidD_GetProductString, TRUE);
DLL_LOAD(ctx, hid.dll, HidD_GetSerialNumberString, TRUE);
DLL_LOAD(ctx, hid.dll, HidP_GetCaps, TRUE);
DLL_LOAD(ctx, hid.dll, HidD_SetNumInputBuffers, TRUE);
DLL_LOAD(ctx, hid.dll, HidD_SetFeature, TRUE);
DLL_LOAD(ctx, hid.dll, HidD_GetFeature, TRUE);
DLL_LOAD(ctx, hid.dll, HidD_GetPhysicalDescriptor, TRUE);
DLL_LOAD(ctx, hid.dll, HidD_GetInputReport, FALSE);
DLL_LOAD(ctx, hid.dll, HidD_SetOutputReport, FALSE);
DLL_LOAD(ctx, hid.dll, HidD_FlushQueue, TRUE);
DLL_LOAD(ctx, hid.dll, HidP_GetValueCaps, TRUE);

HidD_GetHidGuid(&HID_guid);

Expand Down
4 changes: 4 additions & 0 deletions msvc/libusb_dll.dsp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions msvc/libusb_dll_2005.vcproj
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,10 @@
RelativePath="..\libusb\os\threads_windows.c"
>
</File>
<File
RelativePath="..\libusb\os\windows_common.c"
>
</File>
<File
RelativePath="..\libusb\os\windows_usb.c"
>
Expand Down
1 change: 1 addition & 0 deletions msvc/libusb_dll_2010.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@
<ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClInclude Include="..\libusb\os\windows_common.c" />
<ClCompile Include="..\libusb\os\windows_usb.c" />
</ItemGroup>
<ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions msvc/libusb_dll_2010.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
<ClCompile Include="..\libusb\os\threads_windows.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_usb.c">
<Filter>Source Files</Filter>
</ClCompile>
Expand Down
1 change: 1 addition & 0 deletions msvc/libusb_dll_2012.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
<ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_common.c" />
<ClCompile Include="..\libusb\os\windows_usb.c" />
</ItemGroup>
<ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions msvc/libusb_dll_2012.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
<ClCompile Include="..\libusb\os\threads_windows.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_usb.c">
<Filter>Source Files</Filter>
</ClCompile>
Expand Down
1 change: 1 addition & 0 deletions msvc/libusb_dll_2013.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
<ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_common.c" />
<ClCompile Include="..\libusb\os\windows_usb.c" />
</ItemGroup>
<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions msvc/libusb_sources
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@ SOURCES=..\core.c \
..\hotplug.c \
threads_windows.c \
poll_windows.c \
windows_common.c \
windows_usb.c \
..\libusb-1.0.rc
4 changes: 4 additions & 0 deletions msvc/libusb_static.dsp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions msvc/libusb_static_2005.vcproj
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,10 @@
RelativePath="..\libusb\os\poll_windows.c"
>
</File>
<File
RelativePath="..\libusb\os\windows_common.c"
>
</File>
<File
RelativePath="..\libusb\os\windows_usb.c"
>
Expand Down
1 change: 1 addition & 0 deletions msvc/libusb_static_2010.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
<ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_common.c" />
<ClCompile Include="..\libusb\os\windows_usb.c" />
</ItemGroup>
<ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions msvc/libusb_static_2010.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
<ClCompile Include="..\libusb\os\threads_windows.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_common.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\libusb\os\windows_usb.c">
<Filter>Source Files</Filter>
</ClCompile>
Expand Down
1 change: 1 addition & 0 deletions msvc/libusb_static_2012.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
<ClCompile Include="..\libusb\strerror.c" />
<ClCompile Include="..\libusb\sync.c" />
<ClCompile Include="..\libusb\os\threads_windows.c" />
<ClCompile Include="..\libusb\os\windows_common.c" />
<ClCompile Include="..\libusb\os\windows_usb.c" />
</ItemGroup>
<ItemGroup>
Expand Down
Loading