Laszlo, 

Could you explain more? 

Usb Flash drive is managed by UsbMassStorage driver, which is irrelevant with 
UefiScsiLib lib or ScsiDisk driver.

Thanks
Feng

-----Original Message-----
From: edk2-devel [mailto:[email protected]] On Behalf Of Laszlo 
Ersek
Sent: Wednesday, May 4, 2016 12:30 AM
To: edk2-devel-01 <[email protected]>
Cc: Ni, Ruiyu <[email protected]>; Paolo Bonzini <[email protected]>; Tian, 
Feng <[email protected]>; Zeng, Star <[email protected]>
Subject: [edk2] [PATCH] MdeModulePkg: ScsiDiskDxe: cope with broken "Supported 
VPD Pages" VPD page

The USB flash drive with Vendor ID 0x1516 (CompUSA) and Product ID 0x6221 
returns a broken "Supported VPD Pages" VPD page. In particular, the PageLength 
field has the invalid value 0x0602 (decimal 1538).

This prevents the loop from terminating that scans for the Block Limits VPD 
page code in ScsiDiskInquiryDevice():

        for (Index = 0; Index < PageLength; Index++) {

because the Index variable has type UINT8, and it wraps from 255 to 0, without 
ever reaching PageLength (1538), and because 
EFI_SCSI_PAGE_CODE_BLOCK_LIMITS_VPD does not occur at offsets 0 through 255.

* The fix is not to change the type of Index to UINT16 or a wider type.
  Namely, section

    7.8.14 Supported VPD Pages VPD page

  in the "SCSI Primary Commands - 4" (SPC-4) specification names the
  following requirement:

    The supported VPD page list shall contain a list of all VPD page codes
    (see 7.8) implemented by the logical unit in ascending order beginning
    with page code 00h.

  Since page codes are 8-bit unsigned quantities, it follows that the
  maximum size for the Supported VPD Pages VPD page is 0x100 bytes, in
  which every possible page code (0x00 through 0xFF) will be found, before
  the UINT8 offset wraps around.

  (EFI_SCSI_SUPPORTED_VPD_PAGES_VPD_PAGE.SupportedVpdPageList is correctly
  sized as well, in "MdePkg/Include/IndustryStandard/Scsi.h".)

* Instead, add sanity checks that enforce the above requirement. If the
  device breaks the spec, simply fall back to the "Block Limits page
  absent" case.

Cc: Feng Tian <[email protected]>
Cc: Paolo Bonzini <[email protected]>
Cc: Ruiyu Ni <[email protected]>
Cc: Star Zeng <[email protected]>
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1330955
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <[email protected]>
---
 MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c | 37 ++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c 
b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
index dfa5fa32e635..1b75d55231a6 100644
--- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
+++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
@@ -1493,7 +1493,44 @@ ScsiDiskInquiryDevice (
       if (!EFI_ERROR (Status)) {
         PageLength = (SupportedVpdPages->PageLength2 << 8)
                    |  SupportedVpdPages->PageLength1;
+
+        //
+        // Sanity checks for coping with broken devices
+        //
+        if (PageLength > sizeof SupportedVpdPages->SupportedVpdPageList) {
+          DEBUG ((EFI_D_WARN,
+            "%a: invalid PageLength (%u) in Supported VPD Pages page\n",
+            __FUNCTION__, (UINT32)PageLength));
+          PageLength = 0;
+        }
+
+        if ((PageLength > 0) &&
+            (SupportedVpdPages->SupportedVpdPageList[0] !=
+             EFI_SCSI_PAGE_CODE_SUPPORTED_VPD)) {
+          DEBUG ((EFI_D_WARN,
+            "%a: Supported VPD Pages page doesn't start with code 0x%02x\n",
+            __FUNCTION__, EFI_SCSI_PAGE_CODE_SUPPORTED_VPD));
+          PageLength = 0;
+        }
+
+        //
+        // Locate the code for the Block Limits VPD page
+        //
         for (Index = 0; Index < PageLength; Index++) {
+          //
+          // Sanity check
+          //
+          if ((Index > 0) &&
+              (SupportedVpdPages->SupportedVpdPageList[Index] <=
+               SupportedVpdPages->SupportedVpdPageList[Index - 1])) {
+            DEBUG ((EFI_D_WARN,
+              "%a: non-ascending code in Supported VPD Pages page @ %u\n",
+              __FUNCTION__, Index));
+            Index = 0;
+            PageLength = 0;
+            break;
+          }
+
           if (SupportedVpdPages->SupportedVpdPageList[Index] == 
EFI_SCSI_PAGE_CODE_BLOCK_LIMITS_VPD) {
             break;
           }
--
1.8.3.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to