]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c
MdeModulePkg: Fix use-after-free error in InstallConfigurationTable()
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Misc / InstallConfigurationTable.c
old mode 100644 (file)
new mode 100755 (executable)
index 34dc532..dcdeb7f
@@ -1,8 +1,8 @@
 /** @file\r
   UEFI Miscellaneous boot Services InstallConfigurationTable service\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2017, 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
@@ -28,7 +28,7 @@ UINTN mSystemTableAllocateSize = 0;
                          update, or remove, may be NULL.\r
 \r
   @return EFI_SUCCESS               Guid, Table pair added, updated, or removed.\r
-  @return EFI_INVALID_PARAMETER     Input GUID not valid.\r
+  @return EFI_INVALID_PARAMETER     Input GUID is NULL.\r
   @return EFI_NOT_FOUND             Attempted to delete non-existant entry\r
   @return EFI_OUT_OF_RESOURCES      Not enough memory available\r
 \r
@@ -42,6 +42,7 @@ CoreInstallConfigurationTable (
 {\r
   UINTN                   Index;\r
   EFI_CONFIGURATION_TABLE *EfiConfigurationTable;\r
+  EFI_CONFIGURATION_TABLE *OldTable;\r
 \r
   //\r
   // If Guid is NULL, then this operation cannot be performed\r
@@ -68,7 +69,7 @@ CoreInstallConfigurationTable (
     if (Table != NULL) {\r
       //\r
       // If Table is not NULL, then this is a modify operation.\r
-      // Modify the table enty and return.\r
+      // Modify the table entry and return.\r
       //\r
       gDxeCoreST->ConfigurationTable[Index].VendorTable = Table;\r
 \r
@@ -134,15 +135,30 @@ CoreInstallConfigurationTable (
           );\r
 \r
         //\r
-        // Free Old Table\r
+        // Record the old table pointer.\r
         //\r
-        CoreFreePool (gDxeCoreST->ConfigurationTable);\r
-      }\r
+        OldTable = gDxeCoreST->ConfigurationTable;\r
 \r
-      //\r
-      // Update System Table\r
-      //\r
-      gDxeCoreST->ConfigurationTable = EfiConfigurationTable;\r
+        //\r
+        // As the CoreInstallConfigurationTable() may be re-entered by CoreFreePool()\r
+        // in its calling stack, updating System table to the new table pointer must\r
+        // be done before calling CoreFreePool() to free the old table.\r
+        // It can make sure the gDxeCoreST->ConfigurationTable point to the new table\r
+        // and avoid the errors of use-after-free to the old table by the reenter of\r
+        // CoreInstallConfigurationTable() in CoreFreePool()'s calling stack.\r
+        //\r
+        gDxeCoreST->ConfigurationTable = EfiConfigurationTable;\r
+\r
+        //\r
+        // Free the old table after updating System Table to the new table pointer.\r
+        //\r
+        CoreFreePool (OldTable);\r
+      } else {\r
+        //\r
+        // Update System Table\r
+        //\r
+        gDxeCoreST->ConfigurationTable = EfiConfigurationTable;\r
+      }\r
     }\r
 \r
     //\r