From: Chris Dickens Date: Mon, 16 Mar 2020 08:01:51 +0000 (-0700) Subject: core: Move parameter validation from backend to core X-Git-Tag: upstream/1.0.24~119 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=15bd82e9a2935fd4e5c1a9ed83c73d364e92d8ec;p=platform%2Fupstream%2Flibusb.git core: Move parameter validation from backend to core Some functions (e.g. libusb_set_interface_alt_setting()) do not perform sufficient parameter validation, leaving the burden on the backend to catch invalid user input. Much of this validation is common across all backends, yet not every backend implemented it. Fix this by moving parameter validation to the core library functions. This is also a good opportunity to remove the redundant 'num_configurations' field from the libusb_device structure. The value of this field is already contained in the 'device_descriptor' member. Signed-off-by: Chris Dickens --- diff --git a/libusb/core.c b/libusb/core.c index 85d62e4..7ffec1f 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -746,10 +746,10 @@ int usbi_sanitize_device(struct libusb_device *dev) if (num_configurations > USB_MAXCONFIG) { usbi_err(DEVICE_CTX(dev), "too many configurations"); return LIBUSB_ERROR_IO; - } else if (0 == num_configurations) + } else if (0 == num_configurations) { usbi_dbg("zero configurations, maybe an unauthorized device"); + } - dev->num_configurations = num_configurations; return 0; } @@ -1636,6 +1636,8 @@ int API_EXPORTED libusb_set_configuration(libusb_device_handle *dev_handle, int configuration) { usbi_dbg("configuration %d", configuration); + if (configuration < -1 || configuration > UINT8_MAX) + return LIBUSB_ERROR_INVALID_PARAM; return usbi_backend.set_configuration(dev_handle, configuration); } @@ -1673,7 +1675,7 @@ int API_EXPORTED libusb_claim_interface(libusb_device_handle *dev_handle, int r = 0; usbi_dbg("interface %d", interface_number); - if (interface_number >= USB_MAXINTERFACES) + if (interface_number < 0 || interface_number >= USB_MAXINTERFACES) return LIBUSB_ERROR_INVALID_PARAM; if (!dev_handle->dev->attached) @@ -1717,7 +1719,7 @@ int API_EXPORTED libusb_release_interface(libusb_device_handle *dev_handle, int r; usbi_dbg("interface %d", interface_number); - if (interface_number >= USB_MAXINTERFACES) + if (interface_number < 0 || interface_number >= USB_MAXINTERFACES) return LIBUSB_ERROR_INVALID_PARAM; usbi_mutex_lock(&dev_handle->lock); @@ -1761,7 +1763,9 @@ int API_EXPORTED libusb_set_interface_alt_setting(libusb_device_handle *dev_hand { usbi_dbg("interface %d altsetting %d", interface_number, alternate_setting); - if (interface_number >= USB_MAXINTERFACES) + if (interface_number < 0 || interface_number >= USB_MAXINTERFACES) + return LIBUSB_ERROR_INVALID_PARAM; + if (alternate_setting < 0 || alternate_setting > UINT8_MAX) return LIBUSB_ERROR_INVALID_PARAM; usbi_mutex_lock(&dev_handle->lock); @@ -1858,7 +1862,10 @@ int API_EXPORTED libusb_reset_device(libusb_device_handle *dev_handle) int API_EXPORTED libusb_alloc_streams(libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints, int num_endpoints) { - usbi_dbg("streams %u eps %d", (unsigned) num_streams, num_endpoints); + usbi_dbg("streams %u eps %d", (unsigned)num_streams, num_endpoints); + + if (!num_streams || !endpoints || num_endpoints <= 0) + return LIBUSB_ERROR_INVALID_PARAM; if (!dev_handle->dev->attached) return LIBUSB_ERROR_NO_DEVICE; @@ -1887,6 +1894,9 @@ int API_EXPORTED libusb_free_streams(libusb_device_handle *dev_handle, { usbi_dbg("eps %d", num_endpoints); + if (!endpoints || num_endpoints <= 0) + return LIBUSB_ERROR_INVALID_PARAM; + if (!dev_handle->dev->attached) return LIBUSB_ERROR_NO_DEVICE; @@ -1973,6 +1983,9 @@ int API_EXPORTED libusb_kernel_driver_active(libusb_device_handle *dev_handle, { usbi_dbg("interface %d", interface_number); + if (interface_number < 0 || interface_number >= USB_MAXINTERFACES) + return LIBUSB_ERROR_INVALID_PARAM; + if (!dev_handle->dev->attached) return LIBUSB_ERROR_NO_DEVICE; @@ -2008,6 +2021,9 @@ int API_EXPORTED libusb_detach_kernel_driver(libusb_device_handle *dev_handle, { usbi_dbg("interface %d", interface_number); + if (interface_number < 0 || interface_number >= USB_MAXINTERFACES) + return LIBUSB_ERROR_INVALID_PARAM; + if (!dev_handle->dev->attached) return LIBUSB_ERROR_NO_DEVICE; @@ -2042,6 +2058,9 @@ int API_EXPORTED libusb_attach_kernel_driver(libusb_device_handle *dev_handle, { usbi_dbg("interface %d", interface_number); + if (interface_number < 0 || interface_number >= USB_MAXINTERFACES) + return LIBUSB_ERROR_INVALID_PARAM; + if (!dev_handle->dev->attached) return LIBUSB_ERROR_NO_DEVICE; diff --git a/libusb/descriptor.c b/libusb/descriptor.c index 4c7733d..44237dd 100644 --- a/libusb/descriptor.c +++ b/libusb/descriptor.c @@ -617,7 +617,7 @@ int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev, int r; usbi_dbg("index %d", config_index); - if (config_index >= dev->num_configurations) + if (config_index >= dev->device_descriptor.bNumConfigurations) return LIBUSB_ERROR_NOT_FOUND; r = usbi_backend.get_config_descriptor(dev, config_index, tmp, @@ -655,7 +655,7 @@ int usbi_get_config_index_by_value(struct libusb_device *dev, uint8_t i; usbi_dbg("value %d", bConfigurationValue); - for (i = 0; i < dev->num_configurations; i++) { + for (i = 0; i < dev->device_descriptor.bNumConfigurations; i++) { unsigned char tmp[6]; int host_endian; int r = usbi_backend.get_config_descriptor(dev, i, tmp, sizeof(tmp), diff --git a/libusb/io.c b/libusb/io.c index b843d4a..09ccc83 100644 --- a/libusb/io.c +++ b/libusb/io.c @@ -1261,6 +1261,8 @@ struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer( struct libusb_transfer *transfer; assert(iso_packets >= 0); + if (iso_packets < 0) + return NULL; priv_size = PTR_ALIGN(usbi_backend.transfer_priv_size); alloc_size = priv_size diff --git a/libusb/libusbi.h b/libusb/libusbi.h index faaeff3..1fdfc84 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -429,12 +429,11 @@ struct libusb_device { int refcnt; struct libusb_context *ctx; + struct libusb_device *parent_dev; uint8_t bus_number; uint8_t port_number; - struct libusb_device* parent_dev; uint8_t device_address; - uint8_t num_configurations; enum libusb_speed speed; struct list_head list; diff --git a/libusb/os/haiku_usb_raw.cpp b/libusb/os/haiku_usb_raw.cpp index 3162371..63efc17 100644 --- a/libusb/os/haiku_usb_raw.cpp +++ b/libusb/os/haiku_usb_raw.cpp @@ -97,7 +97,7 @@ haiku_get_config_descriptor(struct libusb_device *device, uint8_t config_index, const usb_configuration_descriptor *config = dev->ConfigurationDescriptor(config_index); if (config == NULL) { usbi_err(DEVICE_CTX(device), "failed getting configuration descriptor"); - return LIBUSB_ERROR_INVALID_PARAM; + return LIBUSB_ERROR_IO; } if (len > config->total_length) { len = config->total_length; diff --git a/libusb/os/sunos_usb.c b/libusb/os/sunos_usb.c index 8d0c812..cd32f8b 100644 --- a/libusb/os/sunos_usb.c +++ b/libusb/os/sunos_usb.c @@ -1109,8 +1109,8 @@ sunos_set_configuration(struct libusb_device_handle *handle, int config) if (dpriv->ugenpath == NULL) return (LIBUSB_ERROR_NOT_SUPPORTED); - if (config < 1 || config > dpriv->dev_descr.bNumConfigurations) - return (LIBUSB_ERROR_INVALID_PARAM); + if (config < 1) + return (LIBUSB_ERROR_NOT_SUPPORTED); dpriv->cfgvalue = config; hpriv->config_index = config - 1; @@ -1122,9 +1122,6 @@ int sunos_claim_interface(struct libusb_device_handle *handle, int iface) { usbi_dbg("iface %d", iface); - if (iface < 0) { - return (LIBUSB_ERROR_INVALID_PARAM); - } return (LIBUSB_SUCCESS); } @@ -1135,9 +1132,6 @@ sunos_release_interface(struct libusb_device_handle *handle, int iface) sunos_dev_handle_priv_t *hpriv = usbi_get_device_handle_priv(handle); usbi_dbg("iface %d", iface); - if (iface < 0) { - return (LIBUSB_ERROR_INVALID_PARAM); - } /* XXX: can we release it? */ hpriv->altsetting[iface] = 0; @@ -1154,9 +1148,6 @@ sunos_set_interface_altsetting(struct libusb_device_handle *handle, int iface, usbi_dbg("iface %d, setting %d", iface, altsetting); - if (iface < 0 || altsetting < 0) { - return (LIBUSB_ERROR_INVALID_PARAM); - } if (dpriv->ugenpath == NULL) return (LIBUSB_ERROR_NOT_FOUND); diff --git a/libusb/os/windows_usbdk.c b/libusb/os/windows_usbdk.c index 9c3e8fd..bb370ca 100644 --- a/libusb/os/windows_usbdk.c +++ b/libusb/os/windows_usbdk.c @@ -286,7 +286,6 @@ static void usbdk_device_init(libusb_device *dev, PUSB_DK_DEVICE_INFO info) // Addresses in libusb are 1-based dev->device_address = (uint8_t)(info->Port + 1); - dev->num_configurations = info->DeviceDescriptor.bNumConfigurations; memcpy(&dev->device_descriptor, &info->DeviceDescriptor, LIBUSB_DT_DEVICE_SIZE); switch (info->Speed) { @@ -373,9 +372,6 @@ static int usbdk_get_config_descriptor(struct libusb_device *dev, uint8_t config PUSB_CONFIGURATION_DESCRIPTOR config_header; size_t size; - if (config_index >= dev->num_configurations) - return LIBUSB_ERROR_INVALID_PARAM; - config_header = (PUSB_CONFIGURATION_DESCRIPTOR)priv->config_descriptors[config_index]; size = min(config_header->wTotalLength, len); @@ -390,7 +386,7 @@ static int usbdk_get_config_descriptor_by_value(struct libusb_device *dev, uint8 PUSB_CONFIGURATION_DESCRIPTOR config_header; uint8_t index; - for (index = 0; index < dev->num_configurations; index++) { + for (index = 0; index < dev->device_descriptor.bNumConfigurations; index++) { config_header = priv->config_descriptors[index]; if (config_header->bConfigurationValue == bConfigurationValue) { *buffer = (unsigned char *)priv->config_descriptors[index]; diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c index ef6fbd2..245df90 100644 --- a/libusb/os/windows_winusb.c +++ b/libusb/os/windows_winusb.c @@ -681,27 +681,28 @@ static void cache_config_descriptors(struct libusb_device *dev, HANDLE hub_handl struct libusb_context *ctx = DEVICE_CTX(dev); struct winusb_device_priv *priv = usbi_get_device_priv(dev); DWORD size, ret_size; - uint8_t i; + uint8_t i, num_configurations; USB_CONFIGURATION_DESCRIPTOR_SHORT cd_buf_short; // dummy request PUSB_DESCRIPTOR_REQUEST cd_buf_actual = NULL; // actual request PUSB_CONFIGURATION_DESCRIPTOR cd_data; - if (dev->num_configurations == 0) + num_configurations = priv->dev_descriptor.bNumConfigurations; + if (num_configurations == 0) return; assert(sizeof(USB_DESCRIPTOR_REQUEST) == USB_DESCRIPTOR_REQUEST_SIZE); - priv->config_descriptor = calloc(dev->num_configurations, sizeof(PUSB_CONFIGURATION_DESCRIPTOR)); + priv->config_descriptor = calloc(num_configurations, sizeof(PUSB_CONFIGURATION_DESCRIPTOR)); if (priv->config_descriptor == NULL) { usbi_err(ctx, "could not allocate configuration descriptor array for '%s'", priv->dev_id); return; } - for (i = 0; i <= dev->num_configurations; i++) { + for (i = 0; i <= num_configurations; i++) { safe_free(cd_buf_actual); - if (i == dev->num_configurations) + if (i == num_configurations) break; size = sizeof(cd_buf_short); @@ -860,13 +861,12 @@ static int init_device(struct libusb_device *dev, struct libusb_device *parent_d } memcpy(&priv->dev_descriptor, &(conn_info.DeviceDescriptor), sizeof(USB_DEVICE_DESCRIPTOR)); - dev->num_configurations = conn_info.DeviceDescriptor.bNumConfigurations; priv->active_config = conn_info.CurrentConfigurationValue; if (priv->active_config == 0) { usbi_dbg("0x%x:0x%x found %u configurations (not configured)", priv->dev_descriptor.idVendor, priv->dev_descriptor.idProduct, - dev->num_configurations); + priv->dev_descriptor.bNumConfigurations); SleepEx(50, TRUE); } } while (priv->active_config == 0 && --ginfotimeout >= 0); @@ -876,10 +876,10 @@ static int init_device(struct libusb_device *dev, struct libusb_device *parent_d "forcing current configuration to 1", priv->dev_descriptor.idVendor, priv->dev_descriptor.idProduct, - dev->num_configurations); + priv->dev_descriptor.bNumConfigurations); priv->active_config = 1; } else { - usbi_dbg("found %u configurations (current config: %u)", dev->num_configurations, priv->active_config); + usbi_dbg("found %u configurations (current config: %u)", priv->dev_descriptor.bNumConfigurations, priv->active_config); } // Cache as many config descriptors as we can @@ -957,7 +957,6 @@ static int enumerate_hcd_root_hub(struct libusb_context *ctx, const char *dev_id usbi_dbg("assigning HCD '%s' bus number %u", dev_id, bus_number); priv = usbi_get_device_priv(dev); dev->bus_number = bus_number; - dev->num_configurations = 1; priv->dev_descriptor.bLength = LIBUSB_DT_DEVICE_SIZE; priv->dev_descriptor.bDescriptorType = LIBUSB_DT_DEVICE; priv->dev_descriptor.bDeviceClass = LIBUSB_CLASS_HUB; @@ -1543,10 +1542,6 @@ static int winusb_get_config_descriptor(struct libusb_device *dev, uint8_t confi PUSB_CONFIGURATION_DESCRIPTOR config_header; size_t size; - // config index is zero based - if (config_index >= dev->num_configurations) - return LIBUSB_ERROR_INVALID_PARAM; - if ((priv->config_descriptor == NULL) || (priv->config_descriptor[config_index] == NULL)) return LIBUSB_ERROR_NOT_FOUND; @@ -1567,7 +1562,7 @@ static int winusb_get_config_descriptor_by_value(struct libusb_device *dev, uint if (priv->config_descriptor == NULL) return LIBUSB_ERROR_NOT_FOUND; - for (index = 0; index < dev->num_configurations; index++) { + for (index = 0; index < dev->device_descriptor.bNumConfigurations; index++) { config_header = priv->config_descriptor[index]; if (config_header == NULL) continue; @@ -1641,9 +1636,6 @@ static int winusb_set_configuration(struct libusb_device_handle *dev_handle, int struct winusb_device_priv *priv = usbi_get_device_priv(dev_handle->dev); int r = LIBUSB_SUCCESS; - if (config >= USB_MAXCONFIG) - return LIBUSB_ERROR_INVALID_PARAM; - r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE, LIBUSB_REQUEST_SET_CONFIGURATION, (uint16_t)config, @@ -2478,9 +2470,6 @@ static int winusbx_set_interface_altsetting(int sub_api, struct libusb_device_ha CHECK_WINUSBX_AVAILABLE(sub_api); - if (altsetting > 255) - return LIBUSB_ERROR_INVALID_PARAM; - winusb_handle = handle_priv->interface_handle[iface].api_handle; if (!HANDLE_VALID(winusb_handle)) { usbi_err(HANDLE_CTX(dev_handle), "interface must be claimed first"); @@ -3592,9 +3581,6 @@ static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle CHECK_HID_AVAILABLE; - if (altsetting > 255) - return LIBUSB_ERROR_INVALID_PARAM; - if (altsetting != 0) { usbi_err(HANDLE_CTX(dev_handle), "set interface altsetting not supported for altsetting >0"); return LIBUSB_ERROR_NOT_SUPPORTED; @@ -3615,7 +3601,7 @@ static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itrans OVERLAPPED *overlapped; int current_interface, config; size_t size; - int r = LIBUSB_ERROR_INVALID_PARAM; + int r; UNUSED(sub_api); CHECK_HID_AVAILABLE; diff --git a/libusb/os/windows_winusb.h b/libusb/os/windows_winusb.h index c8d3f15..0340fe7 100644 --- a/libusb/os/windows_winusb.h +++ b/libusb/os/windows_winusb.h @@ -220,8 +220,8 @@ static inline void winusb_device_priv_release(struct libusb_device *dev) free(priv->dev_id); free(priv->path); - if ((dev->num_configurations > 0) && (priv->config_descriptor != NULL)) { - for (i = 0; i < dev->num_configurations; i++) { + if ((priv->dev_descriptor.bNumConfigurations > 0) && (priv->config_descriptor != NULL)) { + for (i = 0; i < priv->dev_descriptor.bNumConfigurations; i++) { if (priv->config_descriptor[i] == NULL) continue; free((UCHAR *)priv->config_descriptor[i] - USB_DESCRIPTOR_REQUEST_SIZE); diff --git a/libusb/version_nano.h b/libusb/version_nano.h index 3804599..a744f2f 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11464 +#define LIBUSB_NANO 11465