summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPete Batard <pbatard@gmail.com>2010-11-18 11:28:30 +0000
committerPete Batard <pbatard@gmail.com>2010-11-18 11:28:30 +0000
commitfa4cd28da39f2398d178ab4a1a55bfc8fba395d6 (patch)
tree70d63580c37c107ad517e2ce342e4a9fc61a2057
parent087fbcd0c90b3626f2e351e38aeb99513da25c3d (diff)
downloadlibusb-fa4cd28da39f2398d178ab4a1a55bfc8fba395d6.tar.gz
fixed device interface path not freed for HID collections
* while additional HID collections might be ignored, existing code assumed that the device interface path was always assigned, which could create a leak * issue reported by Stephano Antonelli
-rw-r--r--libusb/os/windows_usb.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c
index e4970a1..47c6b49 100644
--- a/libusb/os/windows_usb.c
+++ b/libusb/os/windows_usb.c
@@ -1205,21 +1205,22 @@ static int set_composite_interface(struct libusb_context* ctx, struct libusb_dev
// HID devices can have multiple collections (COL##) for each MI_## interface
if (priv->usb_interface[interface_number].path != NULL) {
- usbi_dbg("interface_path[%d] already set - ignoring HID collection: %s",
- interface_number, device_id);
if (api != USB_API_HID) {
- usbi_warn(ctx, "program assertion failed - not an HID collection");
- }
- } else {
- priv->usb_interface[interface_number].path = dev_interface_path;
- priv->usb_interface[interface_number].apib = &usb_api_backend[api];
- if ((api == USB_API_HID) && (priv->hid == NULL)) {
- priv->hid = calloc(1, sizeof(struct hid_device_priv));
+ usbi_warn(ctx, "program assertion failed %s is not an USB HID collection", device_id);
+ return LIBUSB_ERROR_OTHER;
}
- priv->composite_api_flags |= 1<<api;
+ usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
+ interface_number, device_id);
+ return LIBUSB_ERROR_ACCESS;
}
usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
+ priv->usb_interface[interface_number].path = dev_interface_path;
+ priv->usb_interface[interface_number].apib = &usb_api_backend[api];
+ if ((api == USB_API_HID) && (priv->hid == NULL)) {
+ priv->hid = calloc(1, sizeof(struct hid_device_priv));
+ }
+ priv->composite_api_flags |= 1<<api;
return LIBUSB_SUCCESS;
}
@@ -1585,9 +1586,17 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
dev_interface_path = NULL;
} else if (parent_priv->apib == &usb_api_backend[USB_API_COMPOSITE]) {
usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
- r = set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api);
- if (r != LIBUSB_SUCCESS) LOOP_BREAK(r);
- dev_interface_path = NULL;
+ switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api)) {
+ case LIBUSB_SUCCESS:
+ dev_interface_path = NULL;
+ break;
+ case LIBUSB_ERROR_ACCESS:
+ // interface has already been set => make sure dev_interface_path is freed then
+ break;
+ default:
+ LOOP_BREAK(r);
+ break;
+ }
}
break;
}