From 13248b19f6367d9968e4dbec031908da7a34b7f7 Mon Sep 17 00:00:00 2001 From: Yuri Benditovich Date: Wed, 10 Oct 2018 00:22:49 +0300 Subject: [PATCH] Prevent USB operation with non-USB devices This commit aims to address https://bugzilla.redhat.com/show_bug.cgi?id=1575043 The driver definitely may try accessing USB device where it is not USB and sending 'Submit URB' IOCTL down the stack may cause unpredictable result. Current commit change the order of checks when the device is enumerated by its parent device: first ensure this is USB device, then try to get USB-specific information. Signed-off-by: Yuri Benditovich --- UsbDk/FilterDevice.cpp | 46 ++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/UsbDk/FilterDevice.cpp b/UsbDk/FilterDevice.cpp index ad81840..936db67 100644 --- a/UsbDk/FilterDevice.cpp +++ b/UsbDk/FilterDevice.cpp @@ -314,8 +314,33 @@ void CUsbDkHubFilterStrategy::RegisterNewChild(PDEVICE_OBJECT PDO) { CWdmUsbDeviceAccess pdoAccess(PDO); - auto Port = pdoAccess.GetAddress(); + // in case when the device is composite and one of interfaces installed + // under USB class and creates child device (example is composite USB with + // more than one interface and one of them is CD) the PDO can be non-USB + // device. Sending USB requests to it may be problematic as sending URB + // is just internal device control with trivial IOCTL code. + // Before trying to initialize it as USB device we check it is really one. + CObjHolder DevID; + CObjHolder InstanceID; + if (!UsbDkGetWdmDeviceIdentity(PDO, &DevID, &InstanceID)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FILTERDEVICE, "%!FUNC! Cannot query device identity"); + return; + } + + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! Registering new child (PDO: %p):", PDO); + DevID->Dump(); + InstanceID->Dump(); + + // Not a USB device -> do not register + if (!DevID->MatchPrefix(L"USB\\")) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! Not a usb device, skip child registration"); + return; + } + + auto Port = pdoAccess.GetAddress(); if (Port == CWdmDeviceAccess::NO_ADDRESS) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_FILTERDEVICE, "%!FUNC! Cannot read device port number"); @@ -337,25 +362,6 @@ void CUsbDkHubFilterStrategy::RegisterNewChild(PDEVICE_OBJECT PDO) return; } - CObjHolder DevID; - CObjHolder InstanceID; - if (!UsbDkGetWdmDeviceIdentity(PDO, &DevID, &InstanceID)) - { - TraceEvents(TRACE_LEVEL_ERROR, TRACE_FILTERDEVICE, "%!FUNC! Cannot query device identity"); - return; - } - - TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! Registering new child (PDO: %p):", PDO); - DevID->Dump(); - InstanceID->Dump(); - - // Not a USB device -> do not register - if (!DevID->MatchPrefix(L"USB\\")) - { - TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! Not a usb device, skip child registration"); - return; - } - CUsbDkChildDevice::TDescriptorsCache CfgDescriptors(DevDescriptor.bNumConfigurations); if (!CfgDescriptors.Create())