From 2c6acfc33840c5476c1caaaeb93e0f46a34cb655 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sun, 16 Sep 2012 12:44:39 +0000 Subject: [PATCH] =?UTF-8?q?[LIBUSB]:=20Handle=20configuration=20descriptor?= =?UTF-8?q?s=20partial=20reads.=20By=20J=C3=A9r=C3=B4me=20Gardou.=20CORE-6?= =?UTF-8?q?634=20#resolve?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svn path=/trunk/; revision=57312 --- reactos/lib/drivers/libusb/hub_controller.cpp | 96 +++++++++++++------ 1 file changed, 65 insertions(+), 31 deletions(-) diff --git a/reactos/lib/drivers/libusb/hub_controller.cpp b/reactos/lib/drivers/libusb/hub_controller.cpp index 5d41eb103b3..90e6e9cfb8d 100644 --- a/reactos/lib/drivers/libusb/hub_controller.cpp +++ b/reactos/lib/drivers/libusb/hub_controller.cpp @@ -1494,11 +1494,10 @@ CHubController::HandleGetDescriptor( IN OUT PURB Urb) { NTSTATUS Status = STATUS_NOT_IMPLEMENTED; - PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; PUCHAR Buffer; PUSBDEVICE UsbDevice; - ULONG Length; + ULONG Length, BufferLength; DPRINT("[USBLIB] HandleGetDescriptor\n"); @@ -1557,44 +1556,70 @@ CHubController::HandleGetDescriptor( // sanity checks // PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer); - PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR)); + // + // From MSDN + // The caller must allocate a buffer large enough to hold all of this information or the data is truncated without error. + // + BufferLength = Urb->UrbControlDescriptorRequest.TransferBufferLength; + Buffer = (PUCHAR) Urb->UrbControlDescriptorRequest.TransferBuffer; if (Urb->UrbHeader.UsbdDeviceHandle == PVOID(this)) { // // request is for the root bus controller // - RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, &ROOTHUB2_CONFIGURATION_DESCRIPTOR, sizeof(USB_CONFIGURATION_DESCRIPTOR)); - + Length = BufferLength > sizeof(USB_CONFIGURATION_DESCRIPTOR) ? + sizeof(USB_CONFIGURATION_DESCRIPTOR) : BufferLength; + RtlCopyMemory(Buffer, &ROOTHUB2_CONFIGURATION_DESCRIPTOR, Length); + // - // get configuration descriptor, very retarded! + // Check if we still have some space left // - ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer; - - // - // check if buffer can hold interface and endpoint descriptor - // - if (ConfigurationDescriptor->wTotalLength > Urb->UrbControlDescriptorRequest.TransferBufferLength) + if(Length == BufferLength) { // - // buffer too small + // We copied all we could // Status = STATUS_SUCCESS; - ASSERT(FALSE); break; } + // + // Go further + // + Buffer += Length; + BufferLength -= Length; // // copy interface descriptor template // - Buffer = (PUCHAR)(ConfigurationDescriptor + 1); - RtlCopyMemory(Buffer, &ROOTHUB2_INTERFACE_DESCRIPTOR, sizeof(USB_INTERFACE_DESCRIPTOR)); - + Length = BufferLength > sizeof(USB_INTERFACE_DESCRIPTOR) ? + sizeof(USB_INTERFACE_DESCRIPTOR) : BufferLength; + RtlCopyMemory(Buffer, &ROOTHUB2_INTERFACE_DESCRIPTOR, Length); + + // + // Check if we still have some space left + // + if(Length == BufferLength) + { + // + // We copied all we could + // + Status = STATUS_SUCCESS; + break; + } + // + // Go further + // + Buffer += Length; + BufferLength -= Length; + + // // copy end point descriptor template // - Buffer += sizeof(USB_INTERFACE_DESCRIPTOR); - RtlCopyMemory(Buffer, &ROOTHUB2_ENDPOINT_DESCRIPTOR, sizeof(USB_ENDPOINT_DESCRIPTOR)); + Length = BufferLength > sizeof(USB_ENDPOINT_DESCRIPTOR) ? + sizeof(USB_ENDPOINT_DESCRIPTOR) : BufferLength; + RtlCopyMemory(Buffer, &ROOTHUB2_ENDPOINT_DESCRIPTOR, Length); // // done @@ -1621,25 +1646,34 @@ CHubController::HandleGetDescriptor( // get device // UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle); - - if (sizeof(USB_CONFIGURATION_DESCRIPTOR) > Urb->UrbControlDescriptorRequest.TransferBufferLength) + + // + // Allocate temporary buffer + // + BufferLength = UsbDevice->GetConfigurationDescriptorsLength(); + Buffer = (PUCHAR)ExAllocatePoolWithTag(NonPagedPool, BufferLength, TAG_USBLIB); + if(!Buffer) { - // - // buffer too small - // - Urb->UrbControlDescriptorRequest.TransferBufferLength = UsbDevice->GetConfigurationDescriptorsLength(); - - // - // bail out - // - Status = STATUS_SUCCESS; + Status = STATUS_NO_MEMORY; break; } // // perform work in IUSBDevice // - UsbDevice->GetConfigurationDescriptors((PUSB_CONFIGURATION_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength, &Length); + UsbDevice->GetConfigurationDescriptors((PUSB_CONFIGURATION_DESCRIPTOR)Buffer, BufferLength, &Length); + + // + // Copy what we can + // + Length = Urb->UrbControlDescriptorRequest.TransferBufferLength > Length ? + Length : Urb->UrbControlDescriptorRequest.TransferBufferLength; + RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, Buffer, Length); + + // + // Free temporary buffer + // + ExFreePoolWithTag(Buffer, TAG_USBLIB); // // store result size