diff options
author | Pete Batard <pbatard@gmail.com> | 2010-11-18 11:28:30 +0000 |
---|---|---|
committer | Pete Batard <pbatard@gmail.com> | 2010-11-18 11:28:30 +0000 |
commit | fa4cd28da39f2398d178ab4a1a55bfc8fba395d6 (patch) | |
tree | 70d63580c37c107ad517e2ce342e4a9fc61a2057 /libusb | |
parent | 087fbcd0c90b3626f2e351e38aeb99513da25c3d (diff) | |
download | libusb-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
Diffstat (limited to 'libusb')
-rw-r--r-- | libusb/os/windows_usb.c | 35 |
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; } |