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

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