diff --git a/src/add-ons/kernel/drivers/bus/usb/usb_raw.cpp b/src/add-ons/kernel/drivers/bus/usb/usb_raw.cpp index cd7caabb34..56a15573c2 100644 --- a/src/add-ons/kernel/drivers/bus/usb/usb_raw.cpp +++ b/src/add-ons/kernel/drivers/bus/usb/usb_raw.cpp @@ -1,15 +1,17 @@ /* - * Copyright 2006-2010, Haiku Inc. All rights reserved. + * Copyright 2006-2018, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Michael Lotz + * Adrien Destugues */ #include "usb_raw.h" #include #include +#include #include #include #include @@ -311,7 +313,12 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length) } case B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR: + case B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR_ETC: { + if (op == B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR_ETC + && length < sizeof(command.config_etc)) + return B_BUFFER_OVERFLOW; + if (length < sizeof(command.config)) return B_BUFFER_OVERFLOW; @@ -322,10 +329,15 @@ usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length) if (configurationInfo == NULL) break; + size_t sizeToCopy = sizeof(usb_configuration_descriptor); + if (op == B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR_ETC) { + sizeToCopy = std::min(command.config_etc.length, + (size_t)configurationInfo->descr->total_length); + } + if (!IS_USER_ADDRESS(command.config.descriptor) || user_memcpy(command.config.descriptor, - configurationInfo->descr, - sizeof(usb_configuration_descriptor)) != B_OK) { + configurationInfo->descr, sizeToCopy) != B_OK) { return B_BAD_ADDRESS; } diff --git a/src/add-ons/kernel/drivers/bus/usb/usb_raw.h b/src/add-ons/kernel/drivers/bus/usb/usb_raw.h index 54112c2202..9968fa825e 100644 --- a/src/add-ons/kernel/drivers/bus/usb/usb_raw.h +++ b/src/add-ons/kernel/drivers/bus/usb/usb_raw.h @@ -25,6 +25,7 @@ typedef enum { B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC, B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC, B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR_ETC, + B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR_ETC, B_USB_RAW_COMMAND_SET_CONFIGURATION = 0x3000, B_USB_RAW_COMMAND_SET_FEATURE, @@ -74,6 +75,13 @@ typedef union { uint32 config_index; } config; + struct { + status_t status; + usb_configuration_descriptor *descriptor; + uint32 config_index; + size_t length; + } config_etc; + struct { status_t status; uint32 alternate_info;