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)
|
if (DeviceExtension->DeviceDescriptor->iSerialNumber)
|
||||||
{
|
{
|
||||||
// get serial number
|
// 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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
FreeItem(DeviceExtension->DeviceDescriptor);
|
FreeItem(DeviceExtension->DeviceDescriptor);
|
||||||
|
|
|
@ -437,37 +437,60 @@ USBSTOR_PdoHandleQueryInstanceId(
|
||||||
{
|
{
|
||||||
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
PPDO_DEVICE_EXTENSION PDODeviceExtension;
|
||||||
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
PFDO_DEVICE_EXTENSION FDODeviceExtension;
|
||||||
WCHAR Buffer[100];
|
PUSB_STRING_DESCRIPTOR Descriptor;
|
||||||
ULONG Length;
|
ULONG CharCount;
|
||||||
LPWSTR InstanceId;
|
LPWSTR InstanceId;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
PDODeviceExtension = DeviceObject->DeviceExtension;
|
||||||
FDODeviceExtension = (PFDO_DEVICE_EXTENSION)PDODeviceExtension->LowerDeviceObject->DeviceExtension;
|
FDODeviceExtension = PDODeviceExtension->LowerDeviceObject->DeviceExtension;
|
||||||
|
|
||||||
// format instance id
|
Descriptor = FDODeviceExtension->SerialNumber;
|
||||||
if (FDODeviceExtension->SerialNumber)
|
if (Descriptor && (Descriptor->bLength >= sizeof(USB_COMMON_DESCRIPTOR) + sizeof(WCHAR)))
|
||||||
{
|
{
|
||||||
// using serial number from device
|
/* Format the serial number descriptor only if supported by the device */
|
||||||
swprintf(Buffer, L"%s&%c", FDODeviceExtension->SerialNumber->bString, PDODeviceExtension->LUN);
|
CharCount = (Descriptor->bLength - sizeof(USB_COMMON_DESCRIPTOR)) / sizeof(WCHAR) +
|
||||||
|
(sizeof("&") - 1) +
|
||||||
|
(sizeof("F") - 1) + // LUN: 1 char (MAX_LUN)
|
||||||
|
sizeof(ANSI_NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// use instance count and LUN
|
/* Use the instance count and LUN as a fallback */
|
||||||
swprintf(Buffer, L"%04lu&%c", FDODeviceExtension->InstanceCount, PDODeviceExtension->LUN);
|
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 = ExAllocatePoolUninitialized(PagedPool, CharCount * sizeof(WCHAR), USB_STOR_TAG);
|
||||||
|
|
||||||
InstanceId = ExAllocatePoolWithTag(PagedPool, Length * sizeof(WCHAR), USB_STOR_TAG);
|
|
||||||
if (!InstanceId)
|
if (!InstanceId)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
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;
|
Irp->IoStatus.Information = (ULONG_PTR)InstanceId;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define _USBSTOR_H_
|
#define _USBSTOR_H_
|
||||||
|
|
||||||
#include <wdm.h>
|
#include <wdm.h>
|
||||||
|
#include <ntstrsafe.h>
|
||||||
#include <usbdi.h>
|
#include <usbdi.h>
|
||||||
#include <usbbusif.h>
|
#include <usbbusif.h>
|
||||||
#include <usbdlib.h>
|
#include <usbdlib.h>
|
||||||
|
|
Loading…
Reference in a new issue