mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[USBSTOR] Fix PdoHandleQueryInstanceId and increase serial number descriptor size to MAXIMUM_USB_STRING_LENGTH (#6413)
Serial number on some USB devices might exceed the number of 100 characters (e.g. 120 characters on "SanDisk Ultra 3.2Gen1" pendrive) and cause buffer overflow, resulting in usbstor.sys crash. - Use pool allocation for instance ID generation. Fixes stack overflow on USB storage devices with large serial number. - Print the LUN number as a hexadecimal, not as a character. - Verify the serial number descriptor before using it. - Increase the max descriptor size for serial number to MAXIMUM_USB_STRING_LENGTH. This fixes serial number string truncation. Based on suggestions by disean and ThFabba. CORE-17625
This commit is contained in:
parent
398201dca4
commit
20efea8fa4
3 changed files with 40 additions and 16 deletions
|
@ -118,7 +118,7 @@ USBSTOR_GetDescriptors(
|
|||
if (DeviceExtension->DeviceDescriptor->iSerialNumber)
|
||||
{
|
||||
// get serial number
|
||||
Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_STRING_DESCRIPTOR_TYPE, 100 * sizeof(WCHAR), DeviceExtension->DeviceDescriptor->iSerialNumber, 0x0409, (PVOID*)&DeviceExtension->SerialNumber);
|
||||
Status = USBSTOR_GetDescriptor(DeviceExtension->LowerDeviceObject, USB_STRING_DESCRIPTOR_TYPE, MAXIMUM_USB_STRING_LENGTH, DeviceExtension->DeviceDescriptor->iSerialNumber, 0x0409, (PVOID*)&DeviceExtension->SerialNumber);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
FreeItem(DeviceExtension->DeviceDescriptor);
|
||||
|
|
|
@ -437,37 +437,60 @@ USBSTOR_PdoHandleQueryInstanceId(
|
|||
{
|
||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||
WCHAR Buffer[100];
|
||||
ULONG Length;
|
||||
PUSB_STRING_DESCRIPTOR Descriptor;
|
||||
ULONG CharCount;
|
||||
LPWSTR InstanceId;
|
||||
NTSTATUS Status;
|
||||
|
||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
|
||||
PDODeviceExtension = DeviceObject->DeviceExtension;
|
||||
FDODeviceExtension = PDODeviceExtension->LowerDeviceObject->DeviceExtension;
|
||||
|
||||
// format instance id
|
||||
if (FDODeviceExtension->SerialNumber)
|
||||
Descriptor = FDODeviceExtension->SerialNumber;
|
||||
if (Descriptor && (Descriptor->bLength >= sizeof(USB_COMMON_DESCRIPTOR) + sizeof(WCHAR)))
|
||||
{
|
||||
// using serial number from device
|
||||
swprintf(Buffer, L"%s&%c", FDODeviceExtension->SerialNumber->bString, PDODeviceExtension->LUN);
|
||||
/* Format the serial number descriptor only if supported by the device */
|
||||
CharCount = (Descriptor->bLength - sizeof(USB_COMMON_DESCRIPTOR)) / sizeof(WCHAR) +
|
||||
(sizeof("&") - 1) +
|
||||
(sizeof("F") - 1) + // LUN: 1 char (MAX_LUN)
|
||||
sizeof(ANSI_NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// use instance count and LUN
|
||||
swprintf(Buffer, L"%04lu&%c", FDODeviceExtension->InstanceCount, PDODeviceExtension->LUN);
|
||||
/* Use the instance count and LUN as a fallback */
|
||||
CharCount = (sizeof("99999999") - 1) + // Instance Count: 8 chars
|
||||
(sizeof("&") - 1) +
|
||||
(sizeof("F") - 1) + // LUN: 1 char (MAX_LUN)
|
||||
sizeof(ANSI_NULL);
|
||||
}
|
||||
|
||||
Length = wcslen(Buffer) + 1;
|
||||
|
||||
InstanceId = ExAllocatePoolWithTag(PagedPool, Length * sizeof(WCHAR), USB_STOR_TAG);
|
||||
InstanceId = ExAllocatePoolUninitialized(PagedPool, CharCount * sizeof(WCHAR), USB_STOR_TAG);
|
||||
if (!InstanceId)
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
wcscpy(InstanceId, Buffer);
|
||||
if (Descriptor && (Descriptor->bLength >= sizeof(USB_COMMON_DESCRIPTOR) + sizeof(WCHAR)))
|
||||
{
|
||||
Status = RtlStringCchPrintfW(InstanceId,
|
||||
CharCount,
|
||||
L"%s&%x",
|
||||
Descriptor->bString,
|
||||
PDODeviceExtension->LUN);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = RtlStringCchPrintfW(InstanceId,
|
||||
CharCount,
|
||||
L"%04lu&%x",
|
||||
FDODeviceExtension->InstanceCount,
|
||||
PDODeviceExtension->LUN);
|
||||
}
|
||||
|
||||
DPRINT("USBSTOR_PdoHandleQueryInstanceId %S\n", InstanceId);
|
||||
/* This should not happen */
|
||||
ASSERT(NT_SUCCESS(Status));
|
||||
|
||||
DPRINT("USBSTOR_PdoHandleQueryInstanceId '%S'\n", InstanceId);
|
||||
|
||||
Irp->IoStatus.Information = (ULONG_PTR)InstanceId;
|
||||
return STATUS_SUCCESS;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define _USBSTOR_H_
|
||||
|
||||
#include <wdm.h>
|
||||
#include <ntstrsafe.h>
|
||||
#include <usbdi.h>
|
||||
#include <usbbusif.h>
|
||||
#include <usbdlib.h>
|
||||
|
|
Loading…
Reference in a new issue