From: Pete Batard Date: Tue, 17 Jul 2012 16:36:13 +0000 (+0100) Subject: Windows: Fix overflow when handling HID or composite devices X-Git-Tag: upstream/1.0.21~612 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e82c677b5f10a966c89f6b58caa1ae4341260527;p=platform%2Fupstream%2Flibusb.git Windows: Fix overflow when handling HID or composite devices * When libusb_get_device_list() is called mutliple times, the HID device path was unconditionally duplicated in the list of device's interfaces. * Because array boundaries were not checked, this caused overflow and crash. * This patch adds an out of bound check and also ensures that duplication of data, for HID and composite, does not occur * It also renames the private composite_api_flags to api_flags, as well as reorganizes the private attributes * Bug report and part of the fix provided by Toby Gray --- diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c index 3b90d18..8615039 100644 --- a/libusb/os/windows_usb.c +++ b/libusb/os/windows_usb.c @@ -1149,6 +1149,8 @@ static int set_composite_interface(struct libusb_context* ctx, struct libusb_dev struct windows_device_priv *priv = _device_priv(dev); int interface_number; + if (priv->api_flags & USB_API_SET) + return LIBUSB_SUCCESS; if (priv->apib->id != USB_API_COMPOSITE) { usbi_err(ctx, "program assertion failed: '%s' is not composite", device_id); return LIBUSB_ERROR_NO_DEVICE; @@ -1191,7 +1193,7 @@ static int set_composite_interface(struct libusb_context* ctx, struct libusb_dev if (priv->hid == NULL) return LIBUSB_ERROR_NO_MEM; } - priv->composite_api_flags |= 1<api_flags |= USB_API_SET | (1<api_flags & USB_API_SET) + return LIBUSB_SUCCESS; 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; + } 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); priv->hid->nb_interfaces++; + priv->api_flags |= USB_API_SET; return LIBUSB_SUCCESS; } @@ -3983,7 +3992,7 @@ static int composite_open(struct libusb_device_handle *dev_handle) uint8_t flag = 1<composite_api_flags & flag) { + if (priv->api_flags & flag) { r = usb_api_backend[api].open(dev_handle); if (r != LIBUSB_SUCCESS) { return r; @@ -4001,7 +4010,7 @@ static void composite_close(struct libusb_device_handle *dev_handle) uint8_t flag = 1<composite_api_flags & flag) { + if (priv->api_flags & flag) { usb_api_backend[api].close(dev_handle); } flag <<= 1; @@ -4126,7 +4135,7 @@ static int composite_reset_device(struct libusb_device_handle *dev_handle) uint8_t flag = 1<composite_api_flags & flag) { + if (priv->api_flags & flag) { r = usb_api_backend[api].reset_device(dev_handle); if (r != LIBUSB_SUCCESS) { return r; diff --git a/libusb/os/windows_usb.h b/libusb/os/windows_usb.h index 331f75c..cc5c398 100644 --- a/libusb/os/windows_usb.h +++ b/libusb/os/windows_usb.h @@ -120,6 +120,8 @@ const GUID GUID_NULL = { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x #define USB_API_WINUSB 3 #define USB_API_HID 4 #define USB_API_MAX 5 +// The following is used to indicate if the HID or composite extra props have already been set. +#define USB_API_SET (1<parent_dev = NULL; p->path = NULL; p->apib = &usb_api_backend[USB_API_UNSUPPORTED]; - p->composite_api_flags = 0; + p->api_flags = 0; p->hid = NULL; p->active_config = 0; p->config_descriptor = NULL; diff --git a/libusb/version_nano.h b/libusb/version_nano.h index 7238e56..4e1e808 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 10539 +#define LIBUSB_NANO 10540