Blame SOURCES/ovmf-MdeModulePkg-UsbBusDxe-Fix-wrong-buffer-length-used-.patch

bdb79c
From 665567cda914855b29632120174ab28be8c6df58 Mon Sep 17 00:00:00 2001
bdb79c
From: Laszlo Ersek <lersek@redhat.com>
bdb79c
Date: Tue, 9 Apr 2019 16:11:36 +0200
bdb79c
Subject: [PATCH 8/8] MdeModulePkg UsbBusDxe: Fix wrong buffer length used to
bdb79c
 read hub desc
bdb79c
MIME-Version: 1.0
bdb79c
Content-Type: text/plain; charset=UTF-8
bdb79c
Content-Transfer-Encoding: 8bit
bdb79c
bdb79c
Message-id: <20190409141136.27390-2-lersek@redhat.com>
bdb79c
Patchwork-id: 85539
bdb79c
O-Subject:  [RHEL-7.7 ovmf PATCH 1/1] MdeModulePkg UsbBusDxe: Fix wrong buffer
bdb79c
	length used to read hub desc
bdb79c
Bugzilla: 1697534
bdb79c
Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
bdb79c
Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
bdb79c
bdb79c
From: Star Zeng <star.zeng@intel.com>
bdb79c
bdb79c
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=973
bdb79c
bdb79c
HUB descriptor has variable length.
bdb79c
But the code uses stack (HubDesc in UsbHubInit) with fixed length
bdb79c
sizeof(EFI_USB_HUB_DESCRIPTOR) to hold HUB descriptor data.
bdb79c
It uses hard code length value (32 that is greater than
bdb79c
sizeof(EFI_USB_HUB_DESCRIPTOR)) for SuperSpeed path, then there will
bdb79c
be stack overflow when IOMMU is enabled because the Unmap operation
bdb79c
will copy the data from device buffer to host buffer.
bdb79c
And it uses HubDesc->Length for none SuperSpeed path, then there will
bdb79c
be stack overflow when HubDesc->Length is greater than
bdb79c
sizeof(EFI_USB_HUB_DESCRIPTOR).
bdb79c
bdb79c
The patch updates the code to use a big enough buffer to hold the
bdb79c
descriptor data.
bdb79c
The definition EFI_USB_SUPER_SPEED_HUB_DESCRIPTOR is wrong (HubDelay
bdb79c
field should be UINT16 type) and no code is using it, the patch
bdb79c
removes it.
bdb79c
bdb79c
Cc: Jiewen Yao <jiewen.yao@intel.com>
bdb79c
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
bdb79c
Cc: Bret Barkelew <bret.barkelew@microsoft.com>
bdb79c
Contributed-under: TianoCore Contribution Agreement 1.1
bdb79c
Signed-off-by: Star Zeng <star.zeng@intel.com>
bdb79c
Reviewed-by: Bret Barkelew <bret.barkelew@microsoft.com>
bdb79c
(cherry picked from commit acebdf14c985c5c9f50b37ece0b15ada87767359)
bdb79c
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
bdb79c
---
bdb79c
 MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c | 96 +++++++++++----------------------
bdb79c
 MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h | 14 +----
bdb79c
 2 files changed, 32 insertions(+), 78 deletions(-)
bdb79c
bdb79c
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
bdb79c
index fabb441..a962f76 100644
bdb79c
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
bdb79c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
bdb79c
@@ -2,7 +2,7 @@
bdb79c
 
bdb79c
     Unified interface for RootHub and Hub.
bdb79c
 
bdb79c
-Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.
bdb79c
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
bdb79c
 This program and the accompanying materials
bdb79c
 are licensed and made available under the terms and conditions of the BSD License
bdb79c
 which accompanies this distribution.  The full text of the license may be found at
bdb79c
@@ -201,42 +201,7 @@ UsbHubCtrlClearTTBuffer (
bdb79c
 }
bdb79c
 
bdb79c
 /**
bdb79c
-  Usb hub control transfer to get the super speed hub descriptor.
bdb79c
-
bdb79c
-  @param  HubDev                The hub device.
bdb79c
-  @param  Buf                   The buffer to hold the descriptor.
bdb79c
-
bdb79c
-  @retval EFI_SUCCESS           The hub descriptor is retrieved.
bdb79c
-  @retval Others                Failed to retrieve the hub descriptor.
bdb79c
-
bdb79c
-**/
bdb79c
-EFI_STATUS
bdb79c
-UsbHubCtrlGetSuperSpeedHubDesc (
bdb79c
-  IN  USB_DEVICE          *HubDev,
bdb79c
-  OUT VOID                *Buf
bdb79c
-  )
bdb79c
-{
bdb79c
-  EFI_STATUS              Status;
bdb79c
-  
bdb79c
-  Status = EFI_INVALID_PARAMETER;
bdb79c
-  
bdb79c
-  Status = UsbCtrlRequest (
bdb79c
-             HubDev,
bdb79c
-             EfiUsbDataIn,
bdb79c
-             USB_REQ_TYPE_CLASS,
bdb79c
-             USB_HUB_TARGET_HUB,
bdb79c
-             USB_HUB_REQ_GET_DESC,
bdb79c
-             (UINT16) (USB_DESC_TYPE_HUB_SUPER_SPEED << 8),
bdb79c
-             0,
bdb79c
-             Buf,
bdb79c
-             32
bdb79c
-             );
bdb79c
-
bdb79c
-  return Status;
bdb79c
-}
bdb79c
-
bdb79c
-/**
bdb79c
-  Usb hub control transfer to get the hub descriptor.
bdb79c
+  Usb hub control transfer to get the (super speed) hub descriptor.
bdb79c
 
bdb79c
   @param  HubDev                The hub device.
bdb79c
   @param  Buf                   The buffer to hold the descriptor.
bdb79c
@@ -254,6 +219,11 @@ UsbHubCtrlGetHubDesc (
bdb79c
   )
bdb79c
 {
bdb79c
   EFI_STATUS              Status;
bdb79c
+  UINT8                   DescType;
bdb79c
+
bdb79c
+  DescType = (HubDev->Speed == EFI_USB_SPEED_SUPER) ?
bdb79c
+             USB_DESC_TYPE_HUB_SUPER_SPEED :
bdb79c
+             USB_DESC_TYPE_HUB;
bdb79c
 
bdb79c
   Status = UsbCtrlRequest (
bdb79c
              HubDev,
bdb79c
@@ -261,7 +231,7 @@ UsbHubCtrlGetHubDesc (
bdb79c
              USB_REQ_TYPE_CLASS,
bdb79c
              USB_HUB_TARGET_HUB,
bdb79c
              USB_HUB_REQ_GET_DESC,
bdb79c
-             (UINT16) (USB_DESC_TYPE_HUB << 8),
bdb79c
+             (UINT16) (DescType << 8),
bdb79c
              0,
bdb79c
              Buf,
bdb79c
              Len
bdb79c
@@ -475,29 +445,19 @@ UsbHubReadDesc (
bdb79c
 {
bdb79c
   EFI_STATUS              Status;
bdb79c
 
bdb79c
-  if (HubDev->Speed == EFI_USB_SPEED_SUPER) {
bdb79c
-    //
bdb79c
-    // Get the super speed hub descriptor
bdb79c
-    //
bdb79c
-    Status = UsbHubCtrlGetSuperSpeedHubDesc (HubDev, HubDesc);
bdb79c
-  } else {
bdb79c
-
bdb79c
-    //
bdb79c
-    // First get the hub descriptor length
bdb79c
-    //
bdb79c
-    Status = UsbHubCtrlGetHubDesc (HubDev, HubDesc, 2);
bdb79c
-
bdb79c
-    if (EFI_ERROR (Status)) {
bdb79c
-      return Status;
bdb79c
-    }
bdb79c
+  //
bdb79c
+  // First get the hub descriptor length
bdb79c
+  //
bdb79c
+  Status = UsbHubCtrlGetHubDesc (HubDev, HubDesc, 2);
bdb79c
 
bdb79c
-    //
bdb79c
-    // Get the whole hub descriptor
bdb79c
-    //
bdb79c
-    Status = UsbHubCtrlGetHubDesc (HubDev, HubDesc, HubDesc->Length);
bdb79c
+  if (EFI_ERROR (Status)) {
bdb79c
+    return Status;
bdb79c
   }
bdb79c
 
bdb79c
-  return Status;
bdb79c
+  //
bdb79c
+  // Get the whole hub descriptor
bdb79c
+  //
bdb79c
+  return UsbHubCtrlGetHubDesc (HubDev, HubDesc, HubDesc->Length);
bdb79c
 }
bdb79c
 
bdb79c
 
bdb79c
@@ -690,7 +650,8 @@ UsbHubInit (
bdb79c
   IN USB_INTERFACE        *HubIf
bdb79c
   )
bdb79c
 {
bdb79c
-  EFI_USB_HUB_DESCRIPTOR  HubDesc;
bdb79c
+  UINT8                   HubDescBuffer[256];
bdb79c
+  EFI_USB_HUB_DESCRIPTOR  *HubDesc;
bdb79c
   USB_ENDPOINT_DESC       *EpDesc;
bdb79c
   USB_INTERFACE_SETTING   *Setting;
bdb79c
   EFI_USB_IO_PROTOCOL     *UsbIo;
bdb79c
@@ -725,14 +686,19 @@ UsbHubInit (
bdb79c
     return EFI_DEVICE_ERROR;
bdb79c
   }
bdb79c
 
bdb79c
-  Status = UsbHubReadDesc (HubDev, &HubDesc);
bdb79c
+  //
bdb79c
+  // The length field of descriptor is UINT8 type, so the buffer
bdb79c
+  // with 256 bytes is enough to hold the descriptor data.
bdb79c
+  //
bdb79c
+  HubDesc = (EFI_USB_HUB_DESCRIPTOR *) HubDescBuffer;
bdb79c
+  Status = UsbHubReadDesc (HubDev, HubDesc);
bdb79c
 
bdb79c
   if (EFI_ERROR (Status)) {
bdb79c
     DEBUG (( EFI_D_ERROR, "UsbHubInit: failed to read HUB descriptor %r\n", Status));
bdb79c
     return Status;
bdb79c
   }
bdb79c
 
bdb79c
-  HubIf->NumOfPort = HubDesc.NumPorts;
bdb79c
+  HubIf->NumOfPort = HubDesc->NumPorts;
bdb79c
 
bdb79c
   DEBUG (( EFI_D_INFO, "UsbHubInit: hub %d has %d ports\n", HubDev->Address,HubIf->NumOfPort));
bdb79c
 
bdb79c
@@ -751,7 +717,7 @@ UsbHubInit (
bdb79c
     DEBUG ((EFI_D_INFO, "UsbHubInit: Set Hub Depth as 0x%x\n", Depth));
bdb79c
     UsbHubCtrlSetHubDepth (HubIf->Device, Depth);
bdb79c
     
bdb79c
-    for (Index = 0; Index < HubDesc.NumPorts; Index++) {
bdb79c
+    for (Index = 0; Index < HubDesc->NumPorts; Index++) {
bdb79c
       UsbHubCtrlSetPortFeature (HubIf->Device, Index, USB_HUB_PORT_REMOTE_WAKE_MASK);
bdb79c
     }    
bdb79c
   } else {
bdb79c
@@ -759,15 +725,15 @@ UsbHubInit (
bdb79c
     // Feed power to all the hub ports. It should be ok
bdb79c
     // for both gang/individual powered hubs.
bdb79c
     //
bdb79c
-    for (Index = 0; Index < HubDesc.NumPorts; Index++) {
bdb79c
+    for (Index = 0; Index < HubDesc->NumPorts; Index++) {
bdb79c
       UsbHubCtrlSetPortFeature (HubIf->Device, Index, (EFI_USB_PORT_FEATURE) USB_HUB_PORT_POWER);
bdb79c
     }
bdb79c
 
bdb79c
     //
bdb79c
     // Update for the usb hub has no power on delay requirement
bdb79c
     //
bdb79c
-    if (HubDesc.PwrOn2PwrGood > 0) {
bdb79c
-      gBS->Stall (HubDesc.PwrOn2PwrGood * USB_SET_PORT_POWER_STALL);
bdb79c
+    if (HubDesc->PwrOn2PwrGood > 0) {
bdb79c
+      gBS->Stall (HubDesc->PwrOn2PwrGood * USB_SET_PORT_POWER_STALL);
bdb79c
     }
bdb79c
     UsbHubAckHubStatus (HubIf->Device);
bdb79c
   }
bdb79c
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h
bdb79c
index 4e5fcd8..fe9f1f7 100644
bdb79c
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h
bdb79c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h
bdb79c
@@ -2,7 +2,7 @@
bdb79c
 
bdb79c
     The definition for USB hub.
bdb79c
 
bdb79c
-Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
bdb79c
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
bdb79c
 This program and the accompanying materials
bdb79c
 are licensed and made available under the terms and conditions of the BSD License
bdb79c
 which accompanies this distribution.  The full text of the license may be found at
bdb79c
@@ -115,18 +115,6 @@ typedef struct {
bdb79c
   UINT8           Filler[16];
bdb79c
 } EFI_USB_HUB_DESCRIPTOR;
bdb79c
 
bdb79c
-typedef struct {
bdb79c
-  UINT8           Length;
bdb79c
-  UINT8           DescType;
bdb79c
-  UINT8           NumPorts;
bdb79c
-  UINT16          HubCharacter;
bdb79c
-  UINT8           PwrOn2PwrGood;
bdb79c
-  UINT8           HubContrCurrent;
bdb79c
-  UINT8           HubHdrDecLat;
bdb79c
-  UINT8           HubDelay;
bdb79c
-  UINT8           DeviceRemovable;
bdb79c
-} EFI_USB_SUPER_SPEED_HUB_DESCRIPTOR;
bdb79c
-
bdb79c
 #pragma pack()
bdb79c
 
bdb79c
 
bdb79c
-- 
bdb79c
1.8.3.1
bdb79c