]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Improve robustness when scanning PCI Option ROM.
authorrsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 14 Mar 2012 03:17:17 +0000 (03:17 +0000)
committerrsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 14 Mar 2012 03:17:17 +0000 (03:17 +0000)
Signed-off-by: rsun3
Reviewed-by: geekboy15a
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13095 6f19259b-4bc3-4df7-8a09-765794883524

DuetPkg/PciBusNoEnumerationDxe/PciOptionRomSupport.c
DuetPkg/PciBusNoEnumerationDxe/PciRomTable.c
DuetPkg/PciRootBridgeNoEnumerationDxe/Ia32/PcatIo.c
DuetPkg/PciRootBridgeNoEnumerationDxe/X64/PcatIo.c
IntelFrameworkModulePkg/Csm/BiosThunk/Snp16Dxe/BiosSnp16.c
IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyPci.c
MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c
OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.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
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
index 7395ce2d8b45c9ea3e2a0e87598740367ed5d9f6..fbfc2fadef5c3e586a94353c205c959b6e6cfc38 100644 (file)
@@ -1,6 +1,6 @@
 /*++\r
 \r
-Copyright (c) 2005 - 2008, 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
@@ -436,8 +436,10 @@ CheckForRom (
 \r
           Pcir.ImageLength = 0;\r
 \r
-          if (EfiRomHeader.Signature == 0xaa55) {\r
-\r
+          if (EfiRomHeader.Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE &&\r
+              EfiRomHeader.PcirOffset != 0 &&\r
+              (EfiRomHeader.PcirOffset & 3) == 0 &&\r
+              RomBarSize + EfiRomHeader.PcirOffset + sizeof (PCI_DATA_STRUCTURE) <= MaxRomSize) {\r
             ZeroMem (&Pcir, sizeof(Pcir));\r
             IoDev->Mem.Read (\r
               IoDev, \r
@@ -447,6 +449,12 @@ CheckForRom (
               &Pcir\r
               );\r
 \r
+            if (Pcir.Signature != PCI_DATA_STRUCTURE_SIGNATURE) {\r
+              break;\r
+            }\r
+            if (RomBarSize + Pcir.ImageLength * 512 > MaxRomSize) {\r
+              break;\r
+            }\r
             if ((Pcir.Indicator & 0x80) == 0x00) {\r
               LastImage = FALSE;\r
             }\r
index 5320f560d9f4f07ee2e8607783fb6f5d18c379d2..1e4c218032b6393680c3e37df9853bee07269d1e 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
@@ -436,8 +436,10 @@ CheckForRom (
 \r
           Pcir.ImageLength = 0;\r
 \r
-          if (EfiRomHeader.Signature == 0xaa55) {\r
-\r
+          if (EfiRomHeader.Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE &&\r
+              EfiRomHeader.PcirOffset != 0 &&\r
+              (EfiRomHeader.PcirOffset & 3) == 0 &&\r
+              RomBarSize + EfiRomHeader.PcirOffset + sizeof (PCI_DATA_STRUCTURE) <= MaxRomSize) {\r
             ZeroMem (&Pcir, sizeof(Pcir));\r
             IoDev->Mem.Read (\r
               IoDev, \r
@@ -447,6 +449,12 @@ CheckForRom (
               &Pcir\r
               );\r
 \r
+            if (Pcir.Signature != PCI_DATA_STRUCTURE_SIGNATURE) {\r
+              break;\r
+            }\r
+            if (RomBarSize + Pcir.ImageLength * 512 > MaxRomSize) {\r
+              break;\r
+            }\r
             if ((Pcir.Indicator & 0x80) == 0x00) {\r
               LastImage = FALSE;\r
             }\r
index 2ae8daca738dc861fea0b10bd5ac8ba768d6b317..744a7e3453fb65342481722d29394b49c6d54921 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 1999 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 1999 - 2012, Intel Corporation. All rights reserved.<BR>\r
 \r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
@@ -1226,6 +1226,16 @@ Undi16SimpleNetworkLoadUndi (
 \r
     DEBUG ((DEBUG_INIT, "Option ROM found at %X\n", RomAddress));\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 (PciExpansionRomHeader->PcirOffset == 0 ||\r
+        (PciExpansionRomHeader->PcirOffset & 3) != 0 ||\r
+        RomAddress + PciExpansionRomHeader->PcirOffset + sizeof (PCI_DATA_STRUCTURE) > 0x100000) {\r
+      break;\r
+    }\r
+\r
     PciDataStructure = (PCI_DATA_STRUCTURE *) (RomAddress + PciExpansionRomHeader->PcirOffset);\r
 \r
     if (PciDataStructure->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {\r
index 59f6d905dc38bfa0d09c56056876a3aa14583628..45cdd037e668f664ae15073c2a779783dfc5049d 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 \r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
@@ -304,14 +304,24 @@ GetPciLegacyRom (
   BackupImage   = NULL;\r
   RomHeader.Raw = *Rom;\r
   while (RomHeader.Generic->Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
-    if (*ImageSize < \r
-        RomHeader.Raw - (UINT8 *) *Rom + RomHeader.Generic->PcirOffset + sizeof (PCI_DATA_STRUCTURE)\r
-        ) {\r
-      return EFI_NOT_FOUND;\r
+    if (RomHeader.Generic->PcirOffset == 0 ||\r
+        (RomHeader.Generic->PcirOffset & 3) !=0 ||\r
+        *ImageSize < RomHeader.Raw - (UINT8 *) *Rom + RomHeader.Generic->PcirOffset + sizeof (PCI_DATA_STRUCTURE)) {\r
+      break;\r
     }\r
 \r
     Pcir = (PCI_3_0_DATA_STRUCTURE *) (RomHeader.Raw + RomHeader.Generic->PcirOffset);\r
+    //\r
+    // Check signature in the PCI Data Structure.\r
+    //\r
+    if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {\r
+      break;\r
+    }\r
 \r
+    if ((UINTN)(RomHeader.Raw - (UINT8 *) *Rom) + Pcir->ImageLength * 512 > *ImageSize) {\r
+      break;\r
+    }\r
+    \r
     if (Pcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) {\r
       Match = FALSE;\r
       if (Pcir->VendorId == VendorId) {\r
@@ -2875,8 +2885,21 @@ LegacyBiosInstallPciRom (
     }\r
 \r
     LocalRomImage = *RomImage;\r
+    if (((PCI_EXPANSION_ROM_HEADER *) LocalRomImage)->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE ||\r
+        ((PCI_EXPANSION_ROM_HEADER *) LocalRomImage)->PcirOffset == 0 ||\r
+        (((PCI_EXPANSION_ROM_HEADER *) LocalRomImage)->PcirOffset & 3 ) != 0) {\r
+      mVgaInstallationInProgress = FALSE;\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+    \r
     Pcir = (PCI_3_0_DATA_STRUCTURE *)\r
            ((UINT8 *) LocalRomImage + ((PCI_EXPANSION_ROM_HEADER *) LocalRomImage)->PcirOffset);\r
+\r
+    if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {\r
+      mVgaInstallationInProgress = FALSE;\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+\r
     ImageSize = Pcir->ImageLength * 512;\r
     if (Pcir->Length >= 0x1C) {\r
       OpromRevision = Pcir->Revision;\r
index 8fd0b3dbc6f9d3831288bdd21afcb3f935797efc..84c6f21ca33a79df56b1ac48fe0a403416abd41e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   PCI Rom supporting funtions implementation for PCI Bus module.\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 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
@@ -53,6 +53,7 @@ LocalLoadFile2 (
   UINT32                                    ScratchSize;\r
   VOID                                      *Scratch;\r
   EFI_DECOMPRESS_PROTOCOL                   *Decompress;\r
+  UINT32                                    InitializationSize;\r
 \r
   EfiOpRomImageNode = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *) FilePath;\r
   if ((EfiOpRomImageNode == NULL) ||\r
@@ -76,7 +77,7 @@ LocalLoadFile2 (
 \r
 \r
   Pcir = (PCI_DATA_STRUCTURE *) ((UINT8 *) EfiRomHeader + EfiRomHeader->PcirOffset);\r
-\r
+  ASSERT (Pcir->Signature == PCI_DATA_STRUCTURE_SIGNATURE);\r
 \r
   if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&\r
       (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) &&\r
@@ -85,9 +86,14 @@ LocalLoadFile2 (
       (EfiRomHeader->CompressionType <= EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED)\r
        ) {\r
 \r
-    ImageSize               = (UINT32) EfiRomHeader->InitializationSize * 512;\r
+    ImageSize = Pcir->ImageLength * 512;\r
+    InitializationSize = (UINT32) EfiRomHeader->InitializationSize * 512;\r
+    if (InitializationSize > ImageSize || EfiRomHeader->EfiImageHeaderOffset >=  InitializationSize) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+\r
     ImageBuffer             = (UINT8 *) EfiRomHeader + EfiRomHeader->EfiImageHeaderOffset;\r
-    ImageLength             = ImageSize - EfiRomHeader->EfiImageHeaderOffset;\r
+    ImageLength             = InitializationSize - EfiRomHeader->EfiImageHeaderOffset;\r
 \r
     if (EfiRomHeader->CompressionType != EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
       //\r
@@ -321,23 +327,21 @@ ContainEfiImage (
 {\r
   PCI_EXPANSION_ROM_HEADER  *RomHeader;\r
   PCI_DATA_STRUCTURE        *RomPcir;\r
-  BOOLEAN                   FirstCheck;\r
 \r
-  FirstCheck = TRUE;\r
-  RomHeader  = RomImage;\r
+  RomHeader = RomImage;\r
+  if (RomHeader == NULL) {\r
+    return FALSE;\r
+  }\r
+  ASSERT (RomHeader->Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE);\r
 \r
   while ((UINT8 *) RomHeader < (UINT8 *) RomImage + RomSize) {\r
     if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
-      if (FirstCheck) {\r
-        return FALSE;\r
-      } else {\r
-        RomHeader = (PCI_EXPANSION_ROM_HEADER *) ((UINT8 *) RomHeader + 512);\r
-        continue;\r
-      }\r
+      RomHeader = (PCI_EXPANSION_ROM_HEADER *) ((UINT8 *) RomHeader + 512);\r
+      continue;\r
     }\r
 \r
-    FirstCheck = FALSE;\r
     RomPcir    = (PCI_DATA_STRUCTURE *) ((UINT8 *) RomHeader + RomHeader->PcirOffset);\r
+    ASSERT (RomPcir->Signature == PCI_DATA_STRUCTURE_SIGNATURE);\r
 \r
     if (RomPcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) {\r
       return TRUE;\r
@@ -378,6 +382,7 @@ LoadOpRomImage (
   PCI_DATA_STRUCTURE        *RomPcir;\r
   UINT64                    RomSize;\r
   UINT64                    RomImageSize;\r
+  UINT32                    LegacyImageLength;\r
   UINT8                     *RomInMemory;\r
   UINT8                     CodeType;\r
 \r
@@ -430,6 +435,7 @@ LoadOpRomImage (
   RomBarOffset  = RomBar;\r
   RetStatus     = EFI_NOT_FOUND;\r
   FirstCheck    = TRUE;\r
+  LegacyImageLength = 0;\r
 \r
   do {\r
     PciDevice->PciRootBridgeIo->Mem.Read (\r
@@ -452,6 +458,15 @@ LoadOpRomImage (
 \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
@@ -459,8 +474,18 @@ LoadOpRomImage (
                                       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
@@ -472,7 +497,7 @@ LoadOpRomImage (
   // 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
@@ -635,7 +660,6 @@ ProcessOpRomImage (
   EFI_HANDLE                               ImageHandle;\r
   EFI_STATUS                               Status;\r
   EFI_STATUS                               RetStatus;\r
-  BOOLEAN                                  FirstCheck;\r
   EFI_PCI_EXPANSION_ROM_HEADER             *EfiRomHeader;\r
   PCI_DATA_STRUCTURE                       *Pcir;\r
   EFI_DEVICE_PATH_PROTOCOL                 *PciOptionRomImageDevicePath;\r
@@ -651,21 +675,21 @@ ProcessOpRomImage (
   RomBar        = PciDevice->PciIo.RomImage;\r
   RomBarOffset  = (UINT8 *) RomBar;\r
   RetStatus     = EFI_NOT_FOUND;\r
-  FirstCheck    = TRUE;\r
+\r
+  if (RomBar == 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 += 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
index b0d045df9b5d2cb0cf59002278bd0343ba123bf5..58531a800b2b420f5ee1287002252e407deb3bb3 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Platform BDS customizations.\r
 \r
-  Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2004 - 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
@@ -1489,6 +1489,7 @@ PciRomLoadEfiDriversFromRomImage (
   VOID                          *DecompressedImageBuffer;\r
   UINT32                        ImageLength;\r
   EFI_DECOMPRESS_PROTOCOL       *Decompress;\r
+  UINT32                        InitializationSize;\r
 \r
   FileName = L"PciRomInMemory";\r
 \r
@@ -1503,24 +1504,43 @@ PciRomLoadEfiDriversFromRomImage (
 \r
     EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomOffset;\r
 \r
-    if (EfiRomHeader->Signature != 0xaa55) {\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
+        RomOffset - (UINTN)Rom + EfiRomHeader->PcirOffset + sizeof (PCI_DATA_STRUCTURE) > RomSize) {\r
+      break;\r
+    }\r
     Pcir      = (PCI_DATA_STRUCTURE *) (UINTN) (RomOffset + 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 (RomOffset - (UINTN)Rom + 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) (RomOffset + ImageOffset);\r
-        ImageLength             = ImageSize - ImageOffset;\r
+        ImageLength             = InitializationSize - ImageOffset;\r
         DecompressedImageBuffer = NULL;\r
 \r
         //\r
index 8f1015800003c1851d950c208865d6a8b54a9db1..afc561fb7fc394d6ade0a14b510ae13863338f96 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Main file for LoadPciRom shell Debug1 function.\r
 \r
-  Copyright (c) 2005 - 2011, 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
@@ -221,6 +221,7 @@ LoadEfiDriversFromRomImage (
   VOID                          *DecompressedImageBuffer;\r
   UINT32                        ImageLength;\r
   EFI_DECOMPRESS_PROTOCOL       *Decompress;\r
+  UINT32                        InitializationSize;\r
 \r
   ImageIndex    = 0;\r
   ReturnStatus     = EFI_NOT_FOUND;\r
@@ -230,27 +231,46 @@ LoadEfiDriversFromRomImage (
 \r
     EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomBarOffset;\r
 \r
-    if (EfiRomHeader->Signature != 0xaa55) {\r
+    if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
       ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOADPCIROM_CORRUPT), gShellDebug1HiiHandle, FileName, ImageIndex);\r
 //      PrintToken (STRING_TOKEN (STR_LOADPCIROM_IMAGE_CORRUPT), HiiHandle, ImageIndex);\r
       return ReturnStatus;\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
+\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
-       ) {\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
+      ImageOffset             = EfiRomHeader->EfiImageHeaderOffset;\r
+      InitializationSize      = EfiRomHeader->InitializationSize * 512;\r
 \r
-      if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
-          (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)\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