/** @file\r
UEFI Miscellaneous boot Services InstallConfigurationTable service\r
\r
-Copyright (c) 2006 - 2008, 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
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
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
{\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
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
);\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