]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmp.c
MdeModulePkg/RegularExpressionDxe: Miss null pointer check
[mirror_edk2.git] / MdeModulePkg / Universal / EsrtFmpDxe / EsrtFmp.c
index cc9dd63b53cd694fa1b2de496c0490a68169be30..129e90ca11b424b60262c6fb472bbc923f681a04 100644 (file)
@@ -55,47 +55,34 @@ PrintTable (
 //\r
 #define GROWTH_STEP  10\r
 \r
-//\r
-// Module globals.\r
-//\r
-EFI_EVENT                  mEsrtReadyToBootEvent;\r
-EFI_SYSTEM_RESOURCE_TABLE  *mTable = NULL;\r
-BOOLEAN                    mEsrtInstalled = FALSE;\r
-EFI_EVENT                  mFmpInstallEvent;\r
-VOID                       *mFmpInstallEventRegistration = NULL;\r
-\r
 /**\r
   Install EFI System Resource Table into the UEFI Configuration Table\r
 \r
+  @param[in] Table                  Pointer to the ESRT.\r
+\r
   @return  Status code.\r
 \r
 **/\r
 EFI_STATUS\r
 InstallEfiSystemResourceTableInUefiConfigurationTable (\r
-   VOID\r
+  IN EFI_SYSTEM_RESOURCE_TABLE      *Table\r
   )\r
 {\r
   EFI_STATUS Status;\r
 \r
   Status = EFI_SUCCESS;\r
-  if (!mEsrtInstalled) {\r
-    if (mTable == NULL) {\r
-      DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it is NULL. \n"));\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-    } else if (mTable->FwResourceCount == 0) {\r
-      DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it has zero Entries. \n"));\r
-      Status = EFI_UNSUPPORTED;\r
+  if (Table->FwResourceCount == 0) {\r
+    DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it has zero Entries. \n"));\r
+    Status = EFI_UNSUPPORTED;\r
+  } else {\r
+    //\r
+    // Install the pointer into config table\r
+    //\r
+    Status = gBS->InstallConfigurationTable (&gEfiSystemResourceTableGuid, Table);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table.  Status: %r. \n", Status));\r
     } else {\r
-      //\r
-      // Install the pointer into config table\r
-      //\r
-      Status = gBS->InstallConfigurationTable (&gEfiSystemResourceTableGuid, mTable);\r
-      if (EFI_ERROR (Status)) {\r
-        DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table.  Status: %r. \n", Status));\r
-      } else {\r
-        DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Installed ESRT table. \n"));\r
-        mEsrtInstalled = TRUE;\r
-      }\r
+      DEBUG ((DEBUG_INFO, "EsrtFmpDxe: Installed ESRT table. \n"));\r
     }\r
   }\r
   return Status;\r
@@ -135,15 +122,18 @@ IsSystemFmp (
   given a FMP descriptor.  If the guid is already in the ESRT it\r
   will be ignored.  The ESRT will grow if it does not have enough room.\r
 \r
-  @param[in]  FmpImageInfoBuf    Pointer to the EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
-  @param[in]  FmpVersion         FMP Version.\r
+  @param[in, out] Table             On input, pointer to the pointer to the ESRT.\r
+                                    On output, same as input or pointer to the pointer\r
+                                    to new enlarged ESRT.\r
+  @param[in]      FmpImageInfoBuf   Pointer to the EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
+  @param[in]      FmpVersion        FMP Version.\r
 \r
   @return  Status code.\r
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 CreateEsrtEntry (\r
+  IN OUT EFI_SYSTEM_RESOURCE_TABLE  **Table,\r
   IN EFI_FIRMWARE_IMAGE_DESCRIPTOR  *FmpImageInfoBuf,\r
   IN UINT32                         FmpVersion\r
   )\r
@@ -156,18 +146,11 @@ CreateEsrtEntry (
   Index = 0;\r
   Entry = NULL;\r
 \r
-  //\r
-  // Get our ESRT table.  This should never be null at this point\r
-  //\r
-  if (mTable == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(mTable + 1);\r
+  Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)((*Table) + 1);\r
   //\r
   // Make sure Guid isn't already in the list\r
   //\r
-  for (Index = 0; Index < mTable->FwResourceCount; Index++) {\r
+  for (Index = 0; Index < (*Table)->FwResourceCount; Index++) {\r
     if (CompareGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId)) {\r
       DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: ESRT Entry already exists for FMP Instance with GUID %g\n", &Entry->FwClass));\r
       return EFI_INVALID_PARAMETER;\r
@@ -178,18 +161,8 @@ CreateEsrtEntry (
   //\r
   // Grow table if needed\r
   //\r
-  if (mTable->FwResourceCount >= mTable->FwResourceCountMax) {\r
-    //\r
-    // Can't grow table after installed.\r
-    // Only because didn't add support for this.\r
-    // Would need to re-install ESRT in system table if wanted to support\r
-    //\r
-    if (mEsrtInstalled) {\r
-      DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to install entry because ESRT table needed to grow after table already installed. \n"));\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-\r
-    NewSize  = ((mTable->FwResourceCountMax + GROWTH_STEP) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE);\r
+  if ((*Table)->FwResourceCount >= (*Table)->FwResourceCountMax) {\r
+    NewSize  = (((*Table)->FwResourceCountMax + GROWTH_STEP) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE);\r
     NewTable = AllocateZeroPool (NewSize);\r
     if (NewTable == NULL) {\r
       DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory larger table for ESRT. \n"));\r
@@ -200,8 +173,8 @@ CreateEsrtEntry (
     //\r
     CopyMem (\r
       NewTable,\r
-      mTable,\r
-      ((mTable->FwResourceCountMax) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)\r
+      (*Table),\r
+      (((*Table)->FwResourceCountMax) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)\r
       );\r
     //\r
     // Update max\r
@@ -210,25 +183,25 @@ CreateEsrtEntry (
     //\r
     // Free old table\r
     //\r
-    FreePool (mTable);\r
+    FreePool ((*Table));\r
     //\r
     // Reassign pointer to new table.\r
     //\r
-    mTable = NewTable;\r
+    (*Table) = NewTable;\r
   }\r
 \r
   //\r
   // ESRT table has enough room for the new entry so add new entry\r
   //\r
-  Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(((UINT8 *)mTable) + sizeof (EFI_SYSTEM_RESOURCE_TABLE));\r
+  Entry = (EFI_SYSTEM_RESOURCE_ENTRY *)(((UINT8 *)(*Table)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE));\r
   //\r
   // Move to the location of new entry\r
   //\r
-  Entry = Entry + mTable->FwResourceCount;\r
+  Entry = Entry + (*Table)->FwResourceCount;\r
   //\r
   // Increment resource count\r
   //\r
-  mTable->FwResourceCount++;\r
+  (*Table)->FwResourceCount++;\r
 \r
   CopyGuid (&Entry->FwClass, &FmpImageInfoBuf->ImageTypeId);\r
 \r
@@ -264,23 +237,23 @@ CreateEsrtEntry (
 }\r
 \r
 /**\r
-  Notify function for every Firmware Management Protocol being installed.\r
-  Get the descriptors from FMP Instance and create ESRT entries (ESRE)\r
+  Function to create ESRT based on FMP Instances.\r
+  Create ESRT table, get the descriptors from FMP Instance and\r
+  create ESRT entries (ESRE).\r
 \r
-  @param[in]  Event    The Event that is being processed.\r
-  @param[in]  Context  The Event Context.\r
+  @return Pointer to the ESRT created.\r
 \r
 **/\r
-VOID\r
-EFIAPI\r
-FmpInstallProtocolNotify (\r
-  IN EFI_EVENT  Event,\r
-  IN VOID       *Context\r
+EFI_SYSTEM_RESOURCE_TABLE *\r
+CreateFmpBasedEsrt (\r
+  VOID\r
   )\r
 {\r
   EFI_STATUS                        Status;\r
-  EFI_HANDLE                        Handle;\r
-  UINTN                             BufferSize;\r
+  EFI_SYSTEM_RESOURCE_TABLE         *Table;\r
+  UINTN                             NoProtocols;\r
+  VOID                              **Buffer;\r
+  UINTN                             Index;\r
   EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *Fmp;\r
   UINTN                             DescriptorSize;\r
   EFI_FIRMWARE_IMAGE_DESCRIPTOR     *FmpImageInfoBuf;\r
@@ -292,29 +265,43 @@ FmpInstallProtocolNotify (
   CHAR16                            *PackageVersionName;\r
 \r
   Status             = EFI_SUCCESS;\r
-  Handle             = 0;\r
-  BufferSize         = 0;\r
+  Table              = NULL;\r
+  NoProtocols        = 0;\r
+  Buffer             = NULL;\r
   PackageVersionName = NULL;\r
   FmpImageInfoBuf    = NULL;\r
   FmpImageInfoBufOrg = NULL;\r
   Fmp                = NULL;\r
 \r
-  DEBUG ((DEBUG_INFO, "FMP Installed Notify\n"));\r
-  while (TRUE) {\r
-    BufferSize = sizeof (EFI_HANDLE);\r
-    Status = gBS->LocateHandle (ByRegisterNotify, NULL, mFmpInstallEventRegistration, &BufferSize, &Handle);\r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((DEBUG_WARN, "EsrtFmpDxe: Failed to Locate handle from notify value. Status: %r\n", Status));\r
-      return;\r
-    }\r
+  Status = EfiLocateProtocolBuffer (\r
+             &gEfiFirmwareManagementProtocolGuid,\r
+             &NoProtocols,\r
+             &Buffer\r
+             );\r
+  if (EFI_ERROR(Status) || (Buffer == NULL)) {\r
+    return NULL;\r
+  }\r
 \r
-    Status = gBS->HandleProtocol (Handle, &gEfiFirmwareManagementProtocolGuid, (VOID **)&Fmp);\r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to get FMP for a handle 0x%x\n", Handle));\r
-      continue;\r
-    }\r
-    ImageInfoSize = 0;\r
+  //\r
+  // Allocate Memory for table\r
+  //\r
+  Table = AllocateZeroPool (\r
+             (GROWTH_STEP * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)\r
+             );\r
+  if (Table == NULL) {\r
+    DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory for ESRT.\n"));\r
+    gBS->FreePool (Buffer);\r
+    return NULL;\r
+  }\r
+\r
+  Table->FwResourceCount    = 0;\r
+  Table->FwResourceCountMax = GROWTH_STEP;\r
+  Table->FwResourceVersion  = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION;\r
 \r
+  for (Index = 0; Index < NoProtocols; Index++) {\r
+    Fmp = (EFI_FIRMWARE_MANAGEMENT_PROTOCOL *) Buffer[Index];\r
+\r
+    ImageInfoSize = 0;\r
     Status = Fmp->GetImageInfo (\r
                     Fmp,                         // FMP Pointer\r
                     &ImageInfoSize,              // Buffer Size (in this case 0)\r
@@ -331,7 +318,6 @@ FmpInstallProtocolNotify (
       continue;\r
     }\r
 \r
-    FmpImageInfoBuf = NULL;\r
     FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\r
     if (FmpImageInfoBuf == NULL) {\r
       DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to get memory for descriptors.\n"));\r
@@ -352,7 +338,9 @@ FmpInstallProtocolNotify (
                     );\r
     if (EFI_ERROR (Status)) {\r
       DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failure in GetImageInfo.  Status = %r\n", Status));\r
-      goto CleanUp;\r
+      FreePool (FmpImageInfoBufOrg);\r
+      FmpImageInfoBufOrg = NULL;\r
+      continue;\r
     }\r
 \r
     //\r
@@ -366,7 +354,7 @@ FmpInstallProtocolNotify (
         //\r
         // Create ESRT entry\r
         //\r
-        CreateEsrtEntry (FmpImageInfoBuf, FmpImageInfoDescriptorVer);\r
+        CreateEsrtEntry (&Table, FmpImageInfoBuf, FmpImageInfoDescriptorVer);\r
       }\r
       FmpImageInfoCount--;\r
       //\r
@@ -379,17 +367,12 @@ FmpInstallProtocolNotify (
       FreePool (PackageVersionName);\r
       PackageVersionName = NULL;\r
     }\r
-    if (FmpImageInfoBufOrg != NULL) {\r
-      FreePool (FmpImageInfoBufOrg);\r
-      FmpImageInfoBufOrg = NULL;\r
-    }\r
-  }\r
-\r
-CleanUp:\r
-  if (FmpImageInfoBufOrg != NULL) {\r
     FreePool (FmpImageInfoBufOrg);\r
+    FmpImageInfoBufOrg = NULL;\r
   }\r
-  return;\r
+\r
+  gBS->FreePool (Buffer);\r
+  return Table;\r
 }\r
 \r
 /**\r
@@ -407,14 +390,30 @@ EsrtReadyToBootEventNotify (
   IN VOID       *Context\r
   )\r
 {\r
-  InstallEfiSystemResourceTableInUefiConfigurationTable ();\r
+  EFI_STATUS                 Status;\r
+  EFI_SYSTEM_RESOURCE_TABLE  *Table;\r
+\r
+  Table = CreateFmpBasedEsrt ();\r
+  if (Table != NULL) {\r
+    //\r
+    // Print table on debug builds\r
+    //\r
+    DEBUG_CODE_BEGIN ();\r
+    PrintTable (Table);\r
+    DEBUG_CODE_END ();\r
+\r
+    Status = InstallEfiSystemResourceTableInUefiConfigurationTable (Table);\r
+    if (EFI_ERROR (Status)) {\r
+      FreePool (Table);\r
+    }\r
+  } else {\r
+    DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Can't install ESRT table because it is NULL. \n"));\r
+  }\r
 \r
   //\r
-  // Print table on debug builds\r
+  // Close the event to prevent it be signalled again.\r
   //\r
-  DEBUG_CODE_BEGIN ();\r
-  PrintTable (mTable);\r
-  DEBUG_CODE_END ();\r
+  gBS->CloseEvent (Event);\r
 }\r
 \r
 /**\r
@@ -435,39 +434,7 @@ EsrtFmpEntryPoint (
   )\r
 {\r
   EFI_STATUS  Status;\r
-\r
-  //\r
-  // Allocate Memory for table\r
-  //\r
-  mTable = AllocateZeroPool (\r
-             (GROWTH_STEP * sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) + sizeof (EFI_SYSTEM_RESOURCE_TABLE)\r
-             );\r
-  ASSERT (mTable != NULL);\r
-  if (mTable == NULL) {\r
-    DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to allocate memory for ESRT.\n"));\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  mTable->FwResourceCount    = 0;\r
-  mTable->FwResourceCountMax = GROWTH_STEP;\r
-  mTable->FwResourceVersion  = EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION;\r
-\r
-  //\r
-  // Register notify function for all FMP installed\r
-  //\r
-  mFmpInstallEvent = EfiCreateProtocolNotifyEvent (\r
-                       &gEfiFirmwareManagementProtocolGuid,\r
-                       TPL_CALLBACK,\r
-                       FmpInstallProtocolNotify,\r
-                       NULL,\r
-                       &mFmpInstallEventRegistration\r
-                       );\r
-\r
-  ASSERT (mFmpInstallEvent != NULL);\r
-\r
-  if (mFmpInstallEvent == NULL) {\r
-    DEBUG ((DEBUG_ERROR, "EsrtFmpDxe: Failed to Create Protocol Notify Event for FMP.\n"));\r
-  }\r
+  EFI_EVENT   EsrtReadyToBootEvent;\r
 \r
   //\r
   // Register notify function to install ESRT on ReadyToBoot Event.\r
@@ -476,7 +443,7 @@ EsrtFmpEntryPoint (
              TPL_CALLBACK,\r
              EsrtReadyToBootEventNotify,\r
              NULL,\r
-             &mEsrtReadyToBootEvent\r
+             &EsrtReadyToBootEvent\r
              );\r
 \r
   ASSERT_EFI_ERROR (Status);\r