]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
MdeModulePkg/PciHostBridge: Enhance boundary check in Io/Mem.Read/Write
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciHostBridgeDxe / PciRootBridgeIo.c
index f8a1239ceb1f81bf829893227cba6bc840d4c5d2..2c373e41de4d24a92ad9e9def016505a704a40d6 100644 (file)
@@ -301,6 +301,8 @@ CreateRootBridge (
 \r
   @retval EFI_INVALID_PARAMETER  Buffer is NULL.\r
 \r
+  @retval EFI_INVALID_PARAMETER  Address or Count is invalid.\r
+\r
   @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.\r
 \r
   @retval EFI_UNSUPPORTED        The address range specified by Address, Width,\r
@@ -321,6 +323,7 @@ RootBridgeIoCheckParameter (
   UINT64                                       Base;\r
   UINT64                                       Limit;\r
   UINT32                                       Size;\r
+  UINT64                                       Length;\r
 \r
   //\r
   // Check to see if Buffer is NULL\r
@@ -337,7 +340,7 @@ RootBridgeIoCheckParameter (
   }\r
 \r
   //\r
-  // For FIFO type, the target address won't increase during the access,\r
+  // For FIFO type, the device address won't increase during the access,\r
   // so treat Count as 1\r
   //\r
   if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {\r
@@ -347,6 +350,13 @@ RootBridgeIoCheckParameter (
   Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
   Size  = 1 << Width;\r
 \r
+  //\r
+  // Make sure (Count * Size) doesn't exceed MAX_UINT64\r
+  //\r
+  if (Count > DivU64x32 (MAX_UINT64, Size)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   //\r
   // Check to see if Address is aligned\r
   //\r
@@ -354,6 +364,14 @@ RootBridgeIoCheckParameter (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
+  //\r
+  // Make sure (Address + Count * Size) doesn't exceed MAX_UINT64\r
+  //\r
+  Length = MultU64x32 (Count, Size);\r
+  if (Address > MAX_UINT64 - Length) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   RootBridge = ROOT_BRIDGE_FROM_THIS (This);\r
 \r
   //\r
@@ -372,7 +390,7 @@ RootBridgeIoCheckParameter (
     //\r
     // Allow Legacy IO access\r
     //\r
-    if (Address + MultU64x32 (Count, Size) <= 0x1000) {\r
+    if (Address + Length <= 0x1000) {\r
       if ((RootBridge->Attributes & (\r
            EFI_PCI_ATTRIBUTE_ISA_IO | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_ATTRIBUTE_VGA_IO |\r
            EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO |\r
@@ -386,7 +404,7 @@ RootBridgeIoCheckParameter (
     //\r
     // Allow Legacy MMIO access\r
     //\r
-    if ((Address >= 0xA0000) && (Address + MultU64x32 (Count, Size)) <= 0xC0000) {\r
+    if ((Address >= 0xA0000) && (Address + Length) <= 0xC0000) {\r
       if ((RootBridge->Attributes & EFI_PCI_ATTRIBUTE_VGA_MEMORY) != 0) {\r
         return EFI_SUCCESS;\r
       }\r
@@ -395,7 +413,7 @@ RootBridgeIoCheckParameter (
     // By comparing the Address against Limit we know which range to be used\r
     // for checking\r
     //\r
-    if (Address + MultU64x32 (Count, Size) <= RootBridge->Mem.Limit + 1) {\r
+    if (Address + Length <= RootBridge->Mem.Limit + 1) {\r
       Base = RootBridge->Mem.Base;\r
       Limit = RootBridge->Mem.Limit;\r
     } else {\r
@@ -427,7 +445,7 @@ RootBridgeIoCheckParameter (
       return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (Address + MultU64x32 (Count, Size) > Limit + 1) {\r
+  if (Address + Length > Limit + 1) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r