Hi,When using libusbx on Windows we've discovered that we'd see a crash in set_hid_interface() when attempting to increment the nb_interfaces count.
This was tracked down to being due to our process calling libusb_get_device_list multiple times in the same process. Every time this was called then the HID device path was appended to the list of device's interfaces.
Eventually this causes priv->hid->nb_interfaces to be USB_MAX_INTERFACES. This causes set_hid_interface() to write off the end of the priv->usb_interface array, corrupting the value for priv->hid.
The attached patch fixes this by not adding the same interface path twice. It also adds a check for the interface table getting full.
Regards, Toby
>From 62a0b46e01d256ab38af208aa5a38b43ae1e17a1 Mon Sep 17 00:00:00 2001 From: Sorin Basca <[email protected]> Date: Tue, 10 Jul 2012 11:06:03 +0100 Subject: [PATCH] Windows: Avoiding repeats of HID interfaces. When setting a HID interface, its path would just be added as the next item in the windows_device_priv usb_interface array. If requesting the device list several times within the same context, and when the device gets added and removed repeatedly, the same path was being added. This caused the number of interfaces to go beyond the maximum number of USB interfaces (of 32). This fix adds a check that the path being added is not already present in the interfaces array. If found in the array, success is reported and the number of interfaces doesn't increase anymore. An additional check is added that the interface limit has not been reached. If the limit is reached an error is returned. --- libusb/os/windows_usb.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c index 3b90d18..24f5d42 100644 --- a/libusb/os/windows_usb.c +++ b/libusb/os/windows_usb.c @@ -1200,11 +1200,25 @@ static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* d char* dev_interface_path) { struct windows_device_priv *priv = _device_priv(dev); + size_t i = 0; if (priv->hid == NULL) { usbi_err(ctx, "program assertion failed: parent is not HID"); return LIBUSB_ERROR_NO_DEVICE; } + if (priv->hid->nb_interfaces == USB_MAXINTERFACES) { + usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device"); + return LIBUSB_ERROR_NO_DEVICE; + } + + for(i = 0; i < priv->hid->nb_interfaces; i++) { + if((priv->usb_interface[i].apib == &usb_api_backend[USB_API_HID]) && + (safe_strcmp(priv->usb_interface[i].path, dev_interface_path) == 0)) { + // Avoid adding the same interface path twice + return LIBUSB_SUCCESS; + } + } + priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path; priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID]; usbi_dbg("interface[%d] = %s", priv->hid->nb_interfaces, dev_interface_path); -- 1.7.9
------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________ libusbx-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/libusbx-devel
