]> git.proxmox.com Git - mirror_edk2.git/blobdiff - DuetPkg/PciBusNoEnumerationDxe/PciOptionRomSupport.c
ArmVirtPkg: reinstate timer unmask quirk for Xen
[mirror_edk2.git] / DuetPkg / PciBusNoEnumerationDxe / PciOptionRomSupport.c
index 064b634806ad97aa558d4454ede0d527db370604..28adb2bf2ca3afa07536bd00a1a9c65c550bd7da 100644 (file)
@@ -1,7 +1,7 @@
 /*++\r
 \r
-Copyright (c) 2005 - 2006, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \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
 http://opensource.org/licenses/bsd-license.php                                            \r
@@ -155,6 +155,7 @@ Returns:
   PCI_DATA_STRUCTURE        *RomPcir;\r
   UINT64                    RomSize;\r
   UINT64                    RomImageSize;\r
+  UINT32                    LegacyImageLength;\r
   UINT8                     *RomInMemory;\r
   UINT8                     CodeType;\r
 \r
@@ -207,6 +208,7 @@ Returns:
   RomBarOffset  = RomBar;\r
   retStatus     = EFI_NOT_FOUND;\r
   FirstCheck    = TRUE;\r
+  LegacyImageLength = 0;\r
 \r
   do {\r
     PciDevice->PciRootBridgeIo->Mem.Read (\r
@@ -229,6 +231,15 @@ Returns:
 \r
     FirstCheck  = FALSE;\r
     OffsetPcir  = RomHeader->PcirOffset;\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 (OffsetPcir == 0 ||\r
+       (OffsetPcir & 3) != 0 ||\r
+       RomImageSize + OffsetPcir + sizeof (PCI_DATA_STRUCTURE) > RomSize) {\r
+      break;\r
+    }\r
     PciDevice->PciRootBridgeIo->Mem.Read (\r
                                       PciDevice->PciRootBridgeIo,\r
                                       EfiPciWidthUint8,\r
@@ -236,8 +247,18 @@ Returns:
                                       sizeof (PCI_DATA_STRUCTURE),\r
                                       (UINT8 *) RomPcir\r
                                       );\r
+    //\r
+    // If a valid signature is not present in the PCI Data Structure, no further images can be located.\r
+    //\r
+    if (RomPcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {\r
+      break;\r
+    }\r
+    if (RomImageSize + RomPcir->ImageLength * 512 > RomSize) {\r
+      break;\r
+    }\r
     if (RomPcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {\r
       CodeType = PCI_CODE_TYPE_PCAT_IMAGE;\r
+      LegacyImageLength = ((UINT32)((EFI_LEGACY_EXPANSION_ROM_HEADER *)RomHeader)->Size512) * 512;\r
     }\r
     Indicator     = RomPcir->Indicator;\r
     RomImageSize  = RomImageSize + RomPcir->ImageLength * 512;\r
@@ -249,7 +270,7 @@ Returns:
   // of the legacy length and the PCIR Image Length\r
   //\r
   if (CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {\r
-    RomImageSize = MAX(RomImageSize, (((EFI_LEGACY_EXPANSION_ROM_HEADER *)RomHeader)->Size512 * 512));\r
+    RomImageSize = MAX (RomImageSize, LegacyImageLength);\r
   }\r
 \r
   if (RomImageSize > 0) {\r
@@ -399,7 +420,6 @@ Returns:
   EFI_HANDLE                    ImageHandle;\r
   EFI_STATUS                    Status;\r
   EFI_STATUS                    retStatus;\r
-  BOOLEAN                       FirstCheck;\r
   BOOLEAN                       SkipImage;\r
   UINT32                        DestinationSize;\r
   UINT32                        ScratchSize;\r
@@ -410,6 +430,7 @@ Returns:
   EFI_DECOMPRESS_PROTOCOL       *Decompress;\r
   EFI_PCI_EXPANSION_ROM_HEADER  *EfiRomHeader;\r
   PCI_DATA_STRUCTURE            *Pcir;\r
+  UINT32                        InitializationSize;\r
 \r
   Indicator = 0;\r
 \r
@@ -419,35 +440,36 @@ Returns:
   RomBar        = PciDevice->PciIo.RomImage;\r
   RomBarOffset  = (UINT8 *) RomBar;\r
   retStatus     = EFI_NOT_FOUND;\r
-  FirstCheck    = TRUE;\r
+\r
+  if (RomBarOffset == NULL) {\r
+    return retStatus;\r
+  }\r
+  ASSERT (((EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset)->Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE);\r
 \r
   do {\r
     EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset;\r
     if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
       RomBarOffset = RomBarOffset + 512;\r
-      if (FirstCheck) {\r
-        break;\r
-      } else {\r
-        continue;\r
-      }\r
+      continue;\r
     }\r
 \r
-    FirstCheck  = FALSE;\r
     Pcir        = (PCI_DATA_STRUCTURE *) (RomBarOffset + EfiRomHeader->PcirOffset);\r
+    ASSERT (Pcir->Signature == PCI_DATA_STRUCTURE_SIGNATURE);\r
     ImageSize   = (UINT32) (Pcir->ImageLength * 512);\r
     Indicator   = Pcir->Indicator;\r
 \r
-    if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) && \r
-        (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE)) {\r
+    if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&\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               = (UINT32) (EfiRomHeader->InitializationSize * 512);\r
+      if (InitializationSize <= ImageSize && ImageOffset < InitializationSize) {\r
 \r
         ImageBuffer             = (VOID *) (RomBarOffset + ImageOffset);\r
-        ImageLength             = ImageSize - (UINT32)ImageOffset;\r
+        ImageLength             =  InitializationSize - (UINT32)ImageOffset;\r
         DecompressedImageBuffer = NULL;\r
 \r
         //\r