From 7fbb75928749b74a0964ad159159066967191243 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Mon, 31 Aug 2009 07:48:32 +0000 Subject: Changed the parameters and behaviour of the USB_GetDeviceConfigDescriptor() function so that it now performs size checks and data validations internally, to simplify user code. --- LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c | 39 ++++++++++++++------------- LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h | 36 +++++++++++++++++-------- 2 files changed, 46 insertions(+), 29 deletions(-) (limited to 'LUFA/Drivers/USB') diff --git a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c index 47982b806..4c6fbfdab 100644 --- a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c +++ b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c @@ -31,9 +31,11 @@ #include "ConfigDescriptor.h" #if defined(USB_CAN_BE_HOST) -uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, void* BufferPtr) +uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, + void* BufferPtr, uint16_t BufferSize) { uint8_t ErrorCode; + uint8_t ConfigHeader[sizeof(USB_Descriptor_Configuration_Header_t)]; USB_ControlRequest = (USB_Request_Header_t) { @@ -46,26 +48,27 @@ uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const Conf Pipe_SelectPipe(PIPE_CONTROLPIPE); - if (BufferPtr == NULL) - { - uint8_t ConfigHeader[sizeof(USB_Descriptor_Configuration_Header_t)]; + if ((ErrorCode = USB_Host_SendControlRequest(ConfigHeader)) != HOST_SENDCONTROL_Successful) + return ErrorCode; - ErrorCode = USB_Host_SendControlRequest(ConfigHeader); + #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES) + *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).TotalConfigurationSize; + #else + *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).wTotalLength; + #endif - #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES) - *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).TotalConfigurationSize; - #else - *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).wTotalLength; - #endif - } - else - { - USB_ControlRequest.wLength = *ConfigSizePtr; - - ErrorCode = USB_Host_SendControlRequest(BufferPtr); - } + if (*ConfigSizePtr > BufferSize) + return HOST_GETCONFIG_BuffOverflow; + + USB_ControlRequest.wLength = *ConfigSizePtr; + + if ((ErrorCode = USB_Host_SendControlRequest(BufferPtr)) != HOST_SENDCONTROL_Successful) + return ErrorCode; - return ErrorCode; + if (DESCRIPTOR_TYPE(BufferPtr) != DTYPE_Configuration) + return HOST_GETCONFIG_InvalidData; + + return HOST_GETCONFIG_Successful; } #endif diff --git a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h index a9b0b1423..8c4e2c2db 100644 --- a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h +++ b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h @@ -163,6 +163,23 @@ uint8_t USB_GetNextDescriptorComp(uint16_t* BytesRem, uint8_t** CurrConfigLoc, ConfigComparatorPtr_t ComparatorRoutine); /* Enums: */ + enum USB_Host_GetConfigDescriptor_ErrorCodes_t + { + HOST_GETCONFIG_Successful = 0, /**< No error occurred while retrieving the configuration descriptor */ + HOST_GETCONFIG_DeviceDisconnect = 1, /**< The attached device was disconnected while retrieving the configuration + * descriptor + */ + HOST_GETCONFIG_PipeError = 2, /**< An error occurred in the pipe while sending the request */ + HOST_GETCONFIG_SetupStalled = 3, /**< The attached device stalled the request to retrieve the configuration + * descriptor + */ + HOST_GETCONFIG_SoftwareTimeOut = 4, /**< The request or data transfer timed out */ + HOST_GETCONFIG_BuffOverflow = 5, /**< The device's configuration descriptor is too large to fit into the allocated + * buffer + */ + HOST_GETCONFIG_InvalidData = 6, /**< The device returned invalid configuration descriptor data */ + }; + /** Enum for return values of a descriptor comparator function. */ enum DSearch_Return_ErrorCodes_t { @@ -181,22 +198,19 @@ }; /* Function Prototypes: */ - /** Retrieves the configuration descriptor data or size from an attached device via a standard request. + /** Retrieves the configuration descriptor data from an attached device via a standard request into a buffer, + * including validity and size checking to prevent a buffer overflow. * * \param[in] ConfigNumber Device configuration descriptor number to fetch from the device (usually set to 1 for * single configuration devices) + * \param[in,out] ConfigSizePtr Pointer to a uint16_t for storing the retrieved configuration descriptor size + * \param[out] BufferPtr Pointer to the buffer for storing the configuration descriptor data. + * \param[out] BufferSize Size of the allocated buffer where the configuration descriptor is to be stored * - * \param[in,out] ConfigSizePtr Pointer to a uint16_t for either storing or retrieving the configuration - * descriptor size - * - * \param[out] BufferPtr Pointer to the buffer for storing the configuration descriptor data. If this is - * NULL, the size of the configuration descriptor will be retrieved instead and - * placed in the variable pointed to by ConfigSizePtr. If this is non-NULL, the number - * of bytes indicated by ConfigSizePtr of the configuration descriptor will be loaded - * into the buffer + * \return A value from the \ref USB_Host_GetConfigDescriptor_ErrorCodes_t enum */ - uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, void* BufferPtr) - ATTR_NON_NULL_PTR_ARG(2); + uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, void* BufferPtr, + uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(2, 3); /** Skips to the next sub-descriptor inside the configuration descriptor of the specified type value. * The bytes remaining value is automatically decremented. -- cgit v1.2.3