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 e4735db..dcdeb7f
@@ -1,7 +1,7 @@
 /** @file\r
   UEFI Miscellaneous boot Services InstallConfigurationTable service\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\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
@@ -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