diff options
author | Yuri Benditovich <yuri.benditovich@daynix.com> | 2018-10-10 00:22:49 +0300 |
---|---|---|
committer | sameehj <sameeh.j@gmail.com> | 2018-10-10 11:31:56 +0300 |
commit | 960f44ed2c697178235caa088a04ac38bd8e675c (patch) | |
tree | f602a7e67193a371617d4cc25d0ffd263e54c63c | |
parent | 19667102ee267e42d891a99f383e1e18524b3d18 (diff) |
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 <yuri.benditovich@daynix.com>
-rw-r--r-- | UsbDk/FilterDevice.cpp | 46 |
1 files 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<CRegText> DevID; + CObjHolder<CRegText> 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<CRegText> DevID; - CObjHolder<CRegText> 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()) |