https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3faf5efd49586b46b2c19e7b99e7771b59580125

commit 3faf5efd49586b46b2c19e7b99e7771b59580125
Author:     Victor Perevertkin <[email protected]>
AuthorDate: Sun Mar 31 17:20:27 2019 +0300
Commit:     Victor Perevertkin <[email protected]>
CommitDate: Tue Jun 11 04:39:43 2019 +0300

    [USBSTOR] Better validate SCSI IRPs.
    Patch by Vadim Galyant
---
 drivers/usb/usbstor/disk.c    | 101 +++++++++++++++++++++++++++++++++---------
 drivers/usb/usbstor/usbstor.h |   1 +
 2 files changed, 81 insertions(+), 21 deletions(-)

diff --git a/drivers/usb/usbstor/disk.c b/drivers/usb/usbstor/disk.c
index 984296214cf..b73ca91292c 100644
--- a/drivers/usb/usbstor/disk.c
+++ b/drivers/usb/usbstor/disk.c
@@ -5,6 +5,7 @@
  * COPYRIGHT:   2005-2006 James Tabor
  *              2011-2012 Michael Martin ([email protected])
  *              2011-2013 Johannes Anderwald ([email protected])
+ *              2017 Vadim Galyant
  */
 
 #include "usbstor.h"
@@ -13,6 +14,69 @@
 #include <debug.h>
 
 
+static
+BOOLEAN
+IsRequestValid(PIRP Irp)
+{
+    ULONG TransferLength;
+    PIO_STACK_LOCATION IoStack;
+    PSCSI_REQUEST_BLOCK Srb;
+
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+    Srb = IoStack->Parameters.Scsi.Srb;
+
+    if (Srb->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT))
+    {
+        if ((Srb->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION) == 
SRB_FLAGS_UNSPECIFIED_DIRECTION)
+        {
+            DPRINT1("IsRequestValid: Invalid Srb. Srb->SrbFlags - %X\n", 
Srb->SrbFlags);
+            return FALSE;
+        }
+
+        TransferLength = Srb->DataTransferLength;
+
+        if (Irp->MdlAddress == NULL)
+        {
+            DPRINT1("IsRequestValid: Invalid Srb. Irp->MdlAddress == NULL\n");
+            return FALSE;
+        }
+
+        if (TransferLength == 0)
+        {
+            DPRINT1("IsRequestValid: Invalid Srb. TransferLength == 0\n");
+            return FALSE;
+        }
+
+        if (TransferLength > USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH)
+        {
+            DPRINT1("IsRequestValid: Invalid Srb. TransferLength > 0x10000\n");
+            return FALSE;
+        }
+    }
+    else
+    {
+        if (Srb->DataTransferLength)
+        {
+            DPRINT1("IsRequestValid: Invalid Srb. Srb->DataTransferLength != 
0\n");
+            return FALSE;
+        }
+
+        if (Srb->DataBuffer)
+        {
+            DPRINT1("IsRequestValid: Invalid Srb. Srb->DataBuffer != NULL\n");
+            return FALSE;
+        }
+
+        if (Irp->MdlAddress)
+        {
+            DPRINT1("IsRequestValid: Invalid Srb. Irp->MdlAddress != NULL\n");
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
 NTSTATUS
 USBSTOR_HandleInternalDeviceControl(
     IN PDEVICE_OBJECT DeviceObject,
@@ -35,28 +99,23 @@ USBSTOR_HandleInternalDeviceControl(
         {
             DPRINT("SRB_FUNCTION_EXECUTE_SCSI\n");
 
-            // check if request is valid
-            if (Request->SrbFlags & (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT))
+            if (!IsRequestValid(Irp))
             {
-                // data is transferred with this irp
-                if ((Request->SrbFlags & (SRB_FLAGS_DATA_IN | 
SRB_FLAGS_DATA_OUT)) == (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT) ||
-                    Request->DataTransferLength == 0 ||
-                    Irp->MdlAddress == NULL)
-                {
-                    Status = STATUS_INVALID_PARAMETER;
-                    break;
-                }
+                Status = STATUS_INVALID_PARAMETER;
+                break;
             }
-            else
+
+            if (Request->Cdb[0] == SCSIOP_MODE_SENSE)
             {
-                // sense buffer request
-                if (Request->DataTransferLength || Request->DataBuffer || 
Irp->MdlAddress)
-                {
-                    Status = STATUS_INVALID_PARAMETER;
-                    break;
-                }
+                DPRINT("USBSTOR_Scsi: SRB_FUNCTION_EXECUTE_SCSI - FIXME 
SCSIOP_MODE_SENSE\n");
+                // FIXME Get from registry WriteProtect for 
StorageDevicePolicies;
+                // 
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\StorageDevicePolicies"
+                // QueryTable[0].Name = L"WriteProtect"
             }
 
+            IoMarkIrpPending(Irp);
+            Request->SrbStatus = SRB_STATUS_PENDING;
+
             // add the request
             if (!USBSTOR_QueueAddIrp(PDODeviceExtension->LowerDeviceObject, 
Irp))
             {
@@ -337,8 +396,8 @@ USBSTOR_HandleQueryProperty(
         // fill out descriptor
         AdapterDescriptor->Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
         AdapterDescriptor->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
-        AdapterDescriptor->MaximumTransferLength = MAXULONG; //FIXME compute 
some sane value
-        AdapterDescriptor->MaximumPhysicalPages = 25; //FIXME compute some 
sane value
+        AdapterDescriptor->MaximumTransferLength = 
USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH;
+        AdapterDescriptor->MaximumPhysicalPages = 
USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH / PAGE_SIZE + 1; // See CORE-10515 and 
CORE-10755
         AdapterDescriptor->AlignmentMask = 0;
         AdapterDescriptor->AdapterUsesPio = FALSE;
         AdapterDescriptor->AdapterScansDown = FALSE;
@@ -406,8 +465,8 @@ USBSTOR_HandleDeviceControl(
 
             if (Capabilities)
             {
-                Capabilities->MaximumTransferLength = MAXULONG;
-                Capabilities->MaximumPhysicalPages = 25;
+                Capabilities->MaximumTransferLength = 
USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH;
+                Capabilities->MaximumPhysicalPages = 
USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH / PAGE_SIZE + 1; // See CORE-10515 and 
CORE-10755
                 Capabilities->SupportedAsynchronousEvents = 0;
                 Capabilities->AlignmentMask = 0;
                 Capabilities->TaggedQueuing = FALSE;
diff --git a/drivers/usb/usbstor/usbstor.h b/drivers/usb/usbstor/usbstor.h
index 1ac3e33a55e..6d23a567853 100644
--- a/drivers/usb/usbstor/usbstor.h
+++ b/drivers/usb/usbstor/usbstor.h
@@ -9,6 +9,7 @@
 
 #define USB_STOR_TAG 'sbsu'
 #define USB_MAXCHILDREN              (16)
+#define USBSTOR_DEFAULT_MAX_TRANSFER_LENGTH 0x10000
 
 #define HTONS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned 
short)(n) & 0xFF00) >> 8))
 #define NTOHS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned 
short)(n) & 0xFF00) >> 8))

Reply via email to