]> git.proxmox.com Git - mirror_edk2.git/blobdiff - DuetPkg/PciBusNoEnumerationDxe/PciOptionRomSupport.c
SignedCapsulePkg SystemFirmwareUpdateDxe: Fix failure caused by d69d922
[mirror_edk2.git] / DuetPkg / PciBusNoEnumerationDxe / PciOptionRomSupport.c
index f1af103995192e6fcc6e6932a248e846d421651b..28adb2bf2ca3afa07536bd00a1a9c65c550bd7da 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2005 - 2006, 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
@@ -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