]> git.proxmox.com Git - mirror_edk2.git/blobdiff - DuetPkg/PciBusNoEnumerationDxe/PciRomTable.c
Improve robustness when scanning PCI Option ROM.
[mirror_edk2.git] / DuetPkg / PciBusNoEnumerationDxe / PciRomTable.c
index ed868e2eaaec80df39ba90b856b6aff4c72484ca..5085431b08a2328fe1c32fe5847a5a0e802310e5 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2005 - 2007, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -133,6 +133,7 @@ Returns:
   VOID                          *DecompressedImageBuffer;\r
   UINT32                        ImageLength;\r
   EFI_DECOMPRESS_PROTOCOL       *Decompress;\r
+  UINT32                        InitializationSize;\r
 \r
   RomBar = (VOID *) (UINTN) PciOptionRomDescriptor->RomAddress;\r
   RomSize = (UINTN) PciOptionRomDescriptor->RomLength;\r
@@ -151,24 +152,44 @@ Returns:
 \r
     EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomBarOffset;\r
 \r
-    if (EfiRomHeader->Signature != 0xaa55) {\r
+\r
+    if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
       return retStatus;\r
     }\r
 \r
+    //\r
+    // If the pointer to the PCI Data Structure is invalid, no further images can be located. \r
+    // The PCI Data Structure must be DWORD aligned. \r
+    //\r
+    if (EfiRomHeader->PcirOffset == 0 ||\r
+        (EfiRomHeader->PcirOffset & 3) != 0 ||\r
+        RomBarOffset - (UINTN)RomBar + EfiRomHeader->PcirOffset + sizeof (PCI_DATA_STRUCTURE) > RomSize) {\r
+      break;\r
+    }\r
     Pcir      = (PCI_DATA_STRUCTURE *) (UINTN) (RomBarOffset + EfiRomHeader->PcirOffset);\r
+    //\r
+    // If a valid signature is not present in the PCI Data Structure, no further images can be located.\r
+    //\r
+    if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {\r
+      break;\r
+    }\r
     ImageSize = Pcir->ImageLength * 512;\r
+    if (RomBarOffset - (UINTN)RomBar + ImageSize > RomSize) {\r
+      break;\r
+    }\r
 \r
     if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&\r
-        (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) ) {\r
+        (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) &&\r
+        ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
+         (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER))) {\r
 \r
-      if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
-          (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) ) {\r
+      ImageOffset             = EfiRomHeader->EfiImageHeaderOffset;\r
+      InitializationSize      = EfiRomHeader->InitializationSize * 512;\r
 \r
-        ImageOffset             = EfiRomHeader->EfiImageHeaderOffset;\r
-        ImageSize               = EfiRomHeader->InitializationSize * 512;\r
+      if (InitializationSize <= ImageSize && ImageOffset < InitializationSize) {\r
 \r
         ImageBuffer             = (VOID *) (UINTN) (RomBarOffset + ImageOffset);\r
-        ImageLength             = ImageSize - ImageOffset;\r
+        ImageLength             = InitializationSize - ImageOffset;\r
         DecompressedImageBuffer = NULL;\r
 \r
         //\r