* [edk2-platforms: PATCH v3] MinPlatformPkg/SaveMemoryConfig: Variable may not be locked. @ 2022-02-11 9:02 Chiu, Chasel 2022-02-12 0:47 ` [edk2-devel] " Oram, Isaac W 2022-02-17 1:00 ` Nate DeSimone 0 siblings, 2 replies; 4+ messages in thread From: Chiu, Chasel @ 2022-02-11 9:02 UTC (permalink / raw) To: devel; +Cc: Chiu, Chasel, Nate DeSimone, Liming Gao, Eric Dong From: "Chiu, Chasel" <chasel.chiu@intel.com> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3829 Fixed the bug that existing variable will not be locked when it is identical with hob data by creating LockLargeVariable function, also switched to VariablePolicyProtocol for locking variables. Failing to lock variable could be security vulnerability, so the function will return EFI_ABORTED when it failed and SaveMemoryConfig driver will halt the system for developers to resolve this issue. This patch also modified SaveMemoryConfig driver to be unloaded after execution because it does not produce any service protocol. To achieve this goal the DxeRuntimeVariableWriteLib should close registered ExitBootService events in its DESTRUCTOR. Cc: Nate DeSimone <nathaniel.l.desimone@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Eric Dong <eric.dong@intel.com> Signed-off-by: Chasel Chiu <chasel.chiu@intel.com> --- V3: Updated LargeVariableWriteLib to return EFI_ABORTED when locking variables failed. Also SaveMemoryConfig driver will halt the system in this case for developers to fix such security vulnerability issue. Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c | 27 ++++++++++++++++++++++++--- Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariableWriteLib.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c | 61 +++++++++++++++++++++++++++++++++++++++++++++---------------- Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf | 3 ++- Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h | 25 +++++++++++++++++++++++-- Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf | 8 +++++--- 6 files changed, 209 insertions(+), 30 deletions(-) diff --git a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c index 820585f676..54e11e20bd 100644 --- a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c +++ b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c @@ -2,13 +2,14 @@ This is the driver that locates the MemoryConfigurationData HOB, if it exists, and saves the data to nvRAM. -Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR> +Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include <Base.h> #include <Uefi.h> +#include <Library/BaseLib.h> #include <Library/UefiBootServicesTableLib.h> #include <Library/UefiRuntimeServicesTableLib.h> #include <Library/HobLib.h> @@ -18,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include <Library/BaseMemoryLib.h> #include <Library/LargeVariableReadLib.h> #include <Library/LargeVariableWriteLib.h> +#include <Library/VariableWriteLib.h> #include <Guid/FspNonVolatileStorageHob2.h> /** @@ -86,6 +88,18 @@ SaveMemoryConfigEntryPoint ( Status = GetLargeVariable (L"FspNvsBuffer", &gFspNvsBufferVariableGuid, &BufferSize, VariableData); if (!EFI_ERROR (Status) && (BufferSize == DataSize) && (0 == CompareMem (HobData, VariableData, DataSize))) { DataIsIdentical = TRUE; + // + // No need to update Variable, only lock it. + // + Status = LockLargeVariable (L"FspNvsBuffer", &gFspNvsBufferVariableGuid); + if (EFI_ERROR(Status)) { + // + // Fail to lock variable is security vulnerability and should not happen. + // + DEBUG ((DEBUG_ERROR, "LockVariable is requested but failed unexpectedly!\n")); + ASSERT_EFI_ERROR (Status); + CpuDeadLoop(); + } } FreePool (VariableData); } @@ -96,6 +110,13 @@ SaveMemoryConfigEntryPoint ( if (!DataIsIdentical) { Status = SetLargeVariable (L"FspNvsBuffer", &gFspNvsBufferVariableGuid, TRUE, DataSize, HobData); ASSERT_EFI_ERROR (Status); + if (Status == EFI_ABORTED) { + // + // Fail to lock variable is security vulnerability and should not happen. + // + DEBUG ((DEBUG_ERROR, "LockVariable is requested but failed unexpectedly!\n")); + CpuDeadLoop(); + } DEBUG ((DEBUG_INFO, "Saved size of FSP / MRC Training Data: 0x%x\n", DataSize)); } else { DEBUG ((DEBUG_INFO, "FSP / MRC Training Data is identical to data from last boot, no need to save.\n")); @@ -106,7 +127,7 @@ SaveMemoryConfigEntryPoint ( } // - // This driver cannot be unloaded because DxeRuntimeVariableWriteLib constructor will register ExitBootServices callback. + // This driver does not produce any protocol services, so always unload it. // - return EFI_SUCCESS; + return EFI_REQUEST_UNLOAD_IMAGE; } diff --git a/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariableWriteLib.c b/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariableWriteLib.c index e4b97ef1df..154f6f448f 100644 --- a/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariableWriteLib.c +++ b/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariableWriteLib.c @@ -10,7 +10,7 @@ integer number will be added to the end of the variable name. This number will be incremented for each variable as needed to store the entire data set. - Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> + Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -245,7 +245,7 @@ Done: @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. @retval EFI_WRITE_PROTECTED The variable in question is read-only. @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted. - + @retval EFI_ABORTED LockVariable was requested but failed. @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. **/ @@ -412,7 +412,7 @@ SetLargeVariable ( // all data is saved. // if (LockVariable) { - for (Index = 0; Index < VariablesSaved; Index++) { + for (Index = 0; Index <= VariablesSaved; Index++) { ZeroMem (TempVariableName, MAX_VARIABLE_NAME_SIZE); UnicodeSPrint (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index); @@ -420,7 +420,7 @@ SetLargeVariable ( Status = VarLibVariableRequestToLock (TempVariableName, VendorGuid); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "SetLargeVariable: Error locking variable: Status = %r\n", Status)); - VariablesSaved = 0; + Status = EFI_ABORTED; goto Done; } } @@ -442,9 +442,114 @@ Done: 0, NULL ); - DEBUG ((DEBUG_ERROR, "SetLargeVariable: Error deleting variable: Status = %r\n", Status2)); + if (EFI_ERROR (Status2)) { + DEBUG ((DEBUG_ERROR, "SetLargeVariable: Error deleting variable: Status = %r\n", Status2)); + } } } DEBUG ((DEBUG_ERROR, "SetLargeVariable: Status = %r\n", Status)); return Status; } + +/** + Locks the existing large variable. + + @param[in] VariableName A Null-terminated string that is the name of the vendor's variable. + Each VariableName is unique for each VendorGuid. VariableName must + contain 1 or more characters. If VariableName is an empty string, + then EFI_INVALID_PARAMETER is returned. + @param[in] VendorGuid A unique identifier for the vendor. + @retval EFI_SUCCESS The firmware has successfully locked the variable. + @retval EFI_INVALID_PARAMETER An invalid combination of variable name and GUID was supplied + @retval EFI_UNSUPPORTED The service for locking variable is not ready. + @retval EFI_NOT_FOUND The targeting variable for locking is not present. + @retval EFI_ABORTED Fail to lock variable. +**/ +EFI_STATUS +EFIAPI +LockLargeVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid + ) +{ + CHAR16 TempVariableName[MAX_VARIABLE_NAME_SIZE]; + UINT64 VariableSize; + EFI_STATUS Status; + UINTN Index; + + // + // Check input parameters. + // + if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (!VarLibIsVariableRequestToLockSupported ()) { + return EFI_UNSUPPORTED; + } + + VariableSize = 0; + Index = 0; + ZeroMem (TempVariableName, MAX_VARIABLE_NAME_SIZE); + UnicodeSPrint (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index); + Status = VarLibGetVariable (TempVariableName, VendorGuid, NULL, &VariableSize, NULL); + if (Status == EFI_BUFFER_TOO_SMALL) { + // + // Lock multiple variables. + // + + // + // Lock first variable and continue to rest of the variables. + // + DEBUG ((DEBUG_INFO, "Locking %s, Guid = %g\n", TempVariableName, VendorGuid)); + Status = VarLibVariableRequestToLock (TempVariableName, VendorGuid); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_ERROR, "LockLargeVariable: Failed! Satus = %r\n", Status)); + return EFI_ABORTED; + } + for (Index = 1; Index < MAX_VARIABLE_SPLIT; Index++) { + ZeroMem (TempVariableName, MAX_VARIABLE_NAME_SIZE); + UnicodeSPrint (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index); + + VariableSize = 0; + Status = VarLibGetVariable (TempVariableName, VendorGuid, NULL, &VariableSize, NULL); + if (Status == EFI_BUFFER_TOO_SMALL) { + DEBUG ((DEBUG_INFO, "Locking %s, Guid = %g\n", TempVariableName, VendorGuid)); + Status = VarLibVariableRequestToLock (TempVariableName, VendorGuid); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_ERROR, "LockLargeVariable: Failed! Satus = %r\n", Status)); + return EFI_ABORTED; + } + } else if (Status == EFI_NOT_FOUND) { + // + // No more variables need to lock. + // + return EFI_SUCCESS; + } + } // End of for loop + } else if (Status == EFI_NOT_FOUND) { + // + // Check if it is single variable scenario. + // + VariableSize = 0; + Status = VarLibGetVariable (VariableName, VendorGuid, NULL, &VariableSize, NULL); + if (Status == EFI_BUFFER_TOO_SMALL) { + // + // Lock single variable. + // + DEBUG ((DEBUG_INFO, "Locking %s, Guid = %g\n", VariableName, VendorGuid)); + Status = VarLibVariableRequestToLock (VariableName, VendorGuid); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_ERROR, "LockLargeVariable: Failed! Satus = %r\n", Status)); + return EFI_ABORTED; + } + return EFI_SUCCESS; + } + } + + // + // Here probably means variable not present. + // + return Status; + +} diff --git a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c index 9ed59f8827..28730f858b 100644 --- a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c +++ b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c @@ -10,7 +10,7 @@ Using this library allows code to be written in a generic manner that can be used in DXE or SMM without modification. - Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> + Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -18,14 +18,16 @@ #include <Uefi.h> #include <Guid/EventGroup.h> -#include <Protocol/VariableLock.h> +#include <Library/VariablePolicyHelperLib.h> #include <Library/UefiLib.h> #include <Library/DebugLib.h> #include <Library/UefiBootServicesTableLib.h> #include <Library/UefiRuntimeServicesTableLib.h> -STATIC EDKII_VARIABLE_LOCK_PROTOCOL *mVariableWriteLibVariableLock = NULL; +STATIC EDKII_VARIABLE_POLICY_PROTOCOL *mVariableWriteLibVariablePolicy = NULL; +EFI_EVENT mExitBootServiceEvent; +EFI_EVENT mLegacyBootEvent; /** Sets the value of a variable. @@ -144,7 +146,7 @@ VarLibIsVariableRequestToLockSupported ( VOID ) { - if (mVariableWriteLibVariableLock != NULL) { + if (mVariableWriteLibVariablePolicy != NULL) { return TRUE; } else { return FALSE; @@ -178,16 +180,45 @@ VarLibVariableRequestToLock ( { EFI_STATUS Status = EFI_UNSUPPORTED; - if (mVariableWriteLibVariableLock != NULL) { - Status = mVariableWriteLibVariableLock->RequestToLock ( - mVariableWriteLibVariableLock, - VariableName, - VendorGuid - ); + if (mVariableWriteLibVariablePolicy != NULL) { + Status = RegisterBasicVariablePolicy ( + mVariableWriteLibVariablePolicy, + (CONST EFI_GUID*) VendorGuid, + (CONST CHAR16 *) VariableName, + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_NOW + ); } return Status; } +/** + Close events when driver unloaded. + + @param[in] ImageHandle A handle for the image that is initializing this driver + @param[in] SystemTable A pointer to the EFI system table + + @retval EFI_SUCCESS The initialization finished successfully. +**/ +EFI_STATUS +EFIAPI +DxeRuntimeVariableWriteLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + if (mExitBootServiceEvent != 0) { + gBS->CloseEvent (mExitBootServiceEvent); + } + if (mLegacyBootEvent != 0) { + gBS->CloseEvent (mLegacyBootEvent); + } + return EFI_SUCCESS; +} + /** Exit Boot Services Event notification handler. @@ -202,7 +233,7 @@ DxeRuntimeVariableWriteLibOnExitBootServices ( IN VOID *Context ) { - mVariableWriteLibVariableLock = NULL; + mVariableWriteLibVariablePolicy = NULL; } /** @@ -227,13 +258,11 @@ DxeRuntimeVariableWriteLibConstructor ( ) { EFI_STATUS Status; - EFI_EVENT ExitBootServiceEvent; - EFI_EVENT LegacyBootEvent; // // Locate VariableLockProtocol. // - Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&mVariableWriteLibVariableLock); + Status = gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, NULL, (VOID **)&mVariableWriteLibVariablePolicy); ASSERT_EFI_ERROR (Status); // @@ -245,7 +274,7 @@ DxeRuntimeVariableWriteLibConstructor ( DxeRuntimeVariableWriteLibOnExitBootServices, NULL, &gEfiEventExitBootServicesGuid, - &ExitBootServiceEvent + &mExitBootServiceEvent ); ASSERT_EFI_ERROR (Status); @@ -257,7 +286,7 @@ DxeRuntimeVariableWriteLibConstructor ( TPL_NOTIFY, DxeRuntimeVariableWriteLibOnExitBootServices, NULL, - &LegacyBootEvent + &mLegacyBootEvent ); ASSERT_EFI_ERROR (Status); diff --git a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf index e2dbd2fb49..61e85a6586 100644 --- a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf +++ b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf @@ -1,7 +1,7 @@ ### @file # Component information file for SaveMemoryConfig module # -# Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -25,6 +25,7 @@ BaseMemoryLib LargeVariableReadLib LargeVariableWriteLib + BaseLib [Packages] MdePkg/MdePkg.dec diff --git a/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h b/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h index c847d7f152..64b0090c2c 100644 --- a/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h +++ b/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h @@ -16,7 +16,7 @@ is possible, adjusting the value of PcdMaxVariableSize may provide a simpler solution to this problem. - Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> + Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -52,7 +52,7 @@ @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. @retval EFI_WRITE_PROTECTED The variable in question is read-only. @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted. - + @retval EFI_ABORTED LockVariable was requested but failed. @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. **/ @@ -66,4 +66,25 @@ SetLargeVariable ( IN VOID *Data ); +/** + Locks the existing large variable. + + @param[in] VariableName A Null-terminated string that is the name of the vendor's variable. + Each VariableName is unique for each VendorGuid. VariableName must + contain 1 or more characters. If VariableName is an empty string, + then EFI_INVALID_PARAMETER is returned. + @param[in] VendorGuid A unique identifier for the vendor. + @retval EFI_SUCCESS The firmware has successfully locked the variable. + @retval EFI_INVALID_PARAMETER An invalid combination of variable name and GUID was supplied + @retval EFI_UNSUPPORTED The service for locking variable is not ready. + @retval EFI_NOT_FOUND The targeting variable for locking is not present. + @retval EFI_ABORTED Fail to lock variable. +**/ +EFI_STATUS +EFIAPI +LockLargeVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid + ); + #endif // _LARGE_VARIABLE_WRITE_LIB_H_ diff --git a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf index 704a8ac7cc..f83090c847 100644 --- a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf +++ b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf @@ -10,7 +10,7 @@ # Using this library allows code to be written in a generic manner that can be # used in DXE or SMM without modification. # -# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -24,6 +24,7 @@ MODULE_TYPE = DXE_RUNTIME_DRIVER LIBRARY_CLASS = VariableWriteLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER CONSTRUCTOR = DxeRuntimeVariableWriteLibConstructor + DESTRUCTOR = DxeRuntimeVariableWriteLibDestructor [Packages] MdePkg/MdePkg.dec @@ -37,13 +38,14 @@ UefiLib UefiBootServicesTableLib UefiRuntimeServicesTableLib + VariablePolicyHelperLib [Guids] gEfiEventExitBootServicesGuid ## CONSUMES ## Event [Protocols] gEfiVariableWriteArchProtocolGuid ## CONSUMES - gEdkiiVariableLockProtocolGuid ## CONSUMES + gEdkiiVariablePolicyProtocolGuid ## CONSUMES [Depex] - gEfiVariableWriteArchProtocolGuid AND gEdkiiVariableLockProtocolGuid + gEfiVariableWriteArchProtocolGuid AND gEdkiiVariablePolicyProtocolGuid -- 2.28.0.windows.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [edk2-devel] [edk2-platforms: PATCH v3] MinPlatformPkg/SaveMemoryConfig: Variable may not be locked. 2022-02-11 9:02 [edk2-platforms: PATCH v3] MinPlatformPkg/SaveMemoryConfig: Variable may not be locked Chiu, Chasel @ 2022-02-12 0:47 ` Oram, Isaac W 2022-02-14 0:26 ` Chiu, Chasel 2022-02-17 1:00 ` Nate DeSimone 1 sibling, 1 reply; 4+ messages in thread From: Oram, Isaac W @ 2022-02-12 0:47 UTC (permalink / raw) To: devel@edk2.groups.io, Chiu, Chasel Cc: Desimone, Nathaniel L, Gao, Liming, Dong, Eric Reviewed-by: Isaac Oram <isaac.w.oram@intel.com> Minor code style nits that can be fixed before pushing: These do not need another patch for review, if a maintainer agrees. SaveMemoryConfig.c Line 95 : EFI_ERROR( put a space before ( Line 101, 118: CpuDeadLoop( put a space before ( LargeVariableWriteLib.c: Lines 506, 519, 542: EFI_ERROR( put a space before ( Regards, Isaac -----Original Message----- From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Chiu, Chasel Sent: Friday, February 11, 2022 1:02 AM To: devel@edk2.groups.io Cc: Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Dong, Eric <eric.dong@intel.com> Subject: [edk2-devel] [edk2-platforms: PATCH v3] MinPlatformPkg/SaveMemoryConfig: Variable may not be locked. From: "Chiu, Chasel" <chasel.chiu@intel.com> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3829 Fixed the bug that existing variable will not be locked when it is identical with hob data by creating LockLargeVariable function, also switched to VariablePolicyProtocol for locking variables. Failing to lock variable could be security vulnerability, so the function will return EFI_ABORTED when it failed and SaveMemoryConfig driver will halt the system for developers to resolve this issue. This patch also modified SaveMemoryConfig driver to be unloaded after execution because it does not produce any service protocol. To achieve this goal the DxeRuntimeVariableWriteLib should close registered ExitBootService events in its DESTRUCTOR. Cc: Nate DeSimone <nathaniel.l.desimone@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Eric Dong <eric.dong@intel.com> Signed-off-by: Chasel Chiu <chasel.chiu@intel.com> ---V3:Updated LargeVariableWriteLib to return EFI_ABORTED when locking variables failed.Also SaveMemoryConfig driver will halt the system in this case for developers to fixsuch security vulnerability issue. Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c | 27 ++++++++++++++++++++++++--- Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariableWriteLib.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c | 61 +++++++++++++++++++++++++++++++++++++++++++++---------------- Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf | 3 ++- Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h | 25 +++++++++++++++++++++++-- Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf | 8 +++++--- 6 files changed, 209 insertions(+), 30 deletions(-) diff --git a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c index 820585f676..54e11e20bd 100644 --- a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c +++ b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemo +++ ryConfig.c @@ -2,13 +2,14 @@ This is the driver that locates the MemoryConfigurationData HOB, if it exists, and saves the data to nvRAM. -Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR>+Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include <Base.h> #include <Uefi.h>+#include <Library/BaseLib.h> #include <Library/UefiBootServicesTableLib.h> #include <Library/UefiRuntimeServicesTableLib.h> #include <Library/HobLib.h>@@ -18,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include <Library/BaseMemoryLib.h> #include <Library/LargeVariableReadLib.h> #include <Library/LargeVariableWriteLib.h>+#include <Library/VariableWriteLib.h> #include <Guid/FspNonVolatileStorageHob2.h> /**@@ -86,6 +88,18 @@ SaveMemoryConfigEntryPoint ( Status = GetLargeVariable (L"FspNvsBuffer", &gFspNvsBufferVariableGuid, &BufferSize, VariableData); if (!EFI_ERROR (Status) && (BufferSize == DataSize) && (0 == CompareMem (HobData, VariableData, DataSize))) { DataIsIdentical = TRUE;+ //+ // No need to update Variable, only lock it.+ //+ Status = LockLargeVariable (L"FspNvsBuffer", &gFspNvsBufferVariableGuid);+ if (EFI_ERROR(Status)) {+ //+ // Fail to lock variable is security vulnerability and should not happen.+ //+ DEBUG ((DEBUG_ERROR, "LockVariable is requested but failed unexpectedly!\n"));+ ASSERT_EFI_ERROR (Status);+ CpuDeadLoop();+ } } FreePool (VariableData); }@@ -96,6 +110,13 @@ SaveMemoryConfigEntryPoint ( if (!DataIsIdentical) { Status = SetLargeVariable (L"FspNvsBuffer", &gFspNvsBufferVariableGuid, TRUE, DataSize, HobData); ASSERT_EFI_ERROR (Status);+ if (Status == EFI_ABORTED) {+ //+ // Fail to lock variable is security vulnerability and should not happen.+ //+ DEBUG ((DEBUG_ERROR, "LockVariable is requested but failed unexpectedly!\n"));+ CpuDeadLoop();+ } DEBUG ((DEBUG_INFO, "Saved size of FSP / MRC Training Data: 0x%x\n", DataSize)); } else { DEBUG ((DEBUG_INFO, "FSP / MRC Training Data is identical to data from last boot, no need to save.\n"));@@ -106,7 +127,7 @@ SaveMemoryConfigEntryPoint ( } //- // This driver cannot be unloaded because DxeRuntimeVariableWriteLib constructor will register ExitBootServices callback.+ // This driver does not produce any protocol services, so always unload it. //- return EFI_SUCCESS;+ return EFI_REQUEST_UNLOAD_IMAGE; }diff --git a/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariableWriteLib.c b/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariableWriteLib.c index e4b97ef1df..154f6f448f 100644 --- a/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariableWriteLib.c +++ b/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVa +++ riableWriteLib.c @@ -10,7 +10,7 @@ integer number will be added to the end of the variable name. This number will be incremented for each variable as needed to store the entire data set. - Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>+ Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/@@ -245,7 +245,7 @@ Done: @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. @retval EFI_WRITE_PROTECTED The variable in question is read-only. @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted.-+ @retval EFI_ABORTED LockVariable was requested but failed. @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. **/@@ -412,7 +412,7 @@ SetLargeVariable ( // all data is saved. // if (LockVariable) {- for (Index = 0; Index < VariablesSaved; Index++) {+ for (Index = 0; Index <= VariablesSaved; Index++) { ZeroMem (TempVariableName, MAX_VARIABLE_NAME_SIZE); UnicodeSPrint (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index); @@ -420,7 +420,7 @@ SetLargeVariable ( Status = VarLibVariableRequestToLock (TempVariableName, VendorGuid); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "SetLargeVariable: Error locking variable: Status = %r\n", Status));- VariablesSaved = 0;+ Status = EFI_ABORTED; goto Done; } }@@ -442,9 +442,114 @@ Done: 0, NULL );- DEBUG ((DEBUG_ERROR, "SetLargeVariable: Error deleting variable: Status = %r\n", Status2));+ if (EFI_ERROR (Status2)) {+ DEBUG ((DEBUG_ERROR, "SetLargeVariable: Error deleting variable: Status = %r\n", Status2));+ } } } DEBUG ((DEBUG_ERROR, "SetLargeVariable: Status = %r\n", Status)); return Status; }++/**+ Locks the existing large variable.++ @param[in] VariableName A Null-terminated string that is the name of the vendor's variable.+ Each VariableName is unique for each VendorGuid. VariableName must+ contain 1 or more characters. If VariableName is an empty string,+ then EFI_INVALID_PARAMETER is returned.+ @param[in] VendorGuid A unique identifier for the vendor.+ @retval EFI_SUCCESS The firmware has successfully locked the variable.+ @retval EFI_INVALID_PARAMETER An invalid combination of variable name and GUID was supplied+ @retval EFI_UNSUPPORTED The service for locking variable is not ready.+ @retval EFI_NOT_FOUND The targeting variable for locking is not present.+ @retval EFI_ABORTED Fail to lock variable.+**/+EFI_STATUS+EFIAPI+LockLargeVariable (+ IN CHAR16 *VariableName,+ IN EFI_GUID *VendorGuid+ )+{+ CHAR16 TempVariableName[MAX_VARIABLE_NAME_SIZE];+ UINT64 VariableSize;+ EFI_STATUS Status;+ UINTN Index;++ //+ // Check input parameters.+ //+ if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {+ return EFI_INVALID_PARAMETER;+ }++ if (!VarLibIsVariableRequestToLockSupported ()) {+ return EFI_UNSUPPORTED;+ }++ VariableSize = 0;+ Index = 0;+ ZeroMem (TempVariableName, MAX_VARIABLE_NAME_SIZE);+ UnicodeSPrint (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index);+ Status = VarLibGetVariable (TempVariableName, VendorGuid, NULL, &VariableSize, NULL);+ if (Status == EFI_BUFFER_TOO_SMALL) {+ //+ // Lock multiple variables.+ //++ //+ // Lock first variable and continue to rest of the variables.+ //+ DEBUG ((DEBUG_INFO, "Locking %s, Guid = %g\n", TempVariableName, VendorGuid));+ Status = VarLibVariableRequestToLock (TempVariableName, VendorGuid);+ if (EFI_ERROR(Status)) {+ DEBUG ((DEBUG_ERROR, "LockLargeVariable: Failed! Satus = %r\n", Status));+ return EFI_ABORTED;+ }+ for (Index = 1; Index < MAX_VARIABLE_SPLIT; Index++) {+ ZeroMem (TempVariableName, MAX_VARIABLE_NAME_SIZE);+ UnicodeSPrint (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index);++ VariableSize = 0;+ Status = VarLibGetVariable (TempVariableName, VendorGuid, NULL, &VariableSize, NULL);+ if (Status == EFI_BUFFER_TOO_SMALL) {+ DEBUG ((DEBUG_INFO, "Locking %s, Guid = %g\n", TempVariableName, VendorGuid));+ Status = VarLibVariableRequestToLock (TempVariableName, VendorGuid);+ if (EFI_ERROR(Status)) {+ DEBUG ((DEBUG_ERROR, "LockLargeVariable: Failed! Satus = %r\n", Status));+ return EFI_ABORTED;+ }+ } else if (Status == EFI_NOT_FOUND) {+ //+ // No more variables need to lock.+ //+ return EFI_SUCCESS;+ }+ } // End of for loop+ } else if (Status == EFI_NOT_FOUND) {+ //+ // Check if it is single variable scenario.+ //+ VariableSize = 0;+ Status = VarLibGetVariable (VariableName, VendorGuid, NULL, &VariableSize, NULL);+ if (Status == EFI_BUFFER_TOO_SMALL) {+ //+ // Lock single variable.+ //+ DEBUG ((DEBUG_INFO, "Locking %s, Guid = %g\n", VariableName, VendorGuid));+ Status = VarLibVariableRequestToLock (VariableName, VendorGuid);+ if (EFI_ERROR(Status)) {+ DEBUG ((DEBUG_ERROR, "LockLargeVariable: Failed! Satus = %r\n", Status));+ return EFI_ABORTED;+ }+ return EFI_SUCCESS;+ }+ }++ //+ // Here probably means variable not present.+ //+ return Status;++}diff --git a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c index 9ed59f8827..28730f858b 100644 --- a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c +++ b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/D +++ xeRuntimeVariableWriteLib.c @@ -10,7 +10,7 @@ Using this library allows code to be written in a generic manner that can be used in DXE or SMM without modification. - Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>+ Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/@@ -18,14 +18,16 @@ #include <Uefi.h> #include <Guid/EventGroup.h>-#include <Protocol/VariableLock.h>+#include <Library/VariablePolicyHelperLib.h> #include <Library/UefiLib.h> #include <Library/DebugLib.h> #include <Library/UefiBootServicesTableLib.h> #include <Library/UefiRuntimeServicesTableLib.h> -STATIC EDKII_VARIABLE_LOCK_PROTOCOL *mVariableWriteLibVariableLock = NULL;+STATIC EDKII_VARIABLE_POLICY_PROTOCOL *mVariableWriteLibVariablePolicy = NULL;+EFI_EVENT mExitBootServiceEvent;+EFI_EVENT mLegacyBootEvent; /** Sets the value of a variable.@@ -144,7 +146,7 @@ VarLibIsVariableRequestToLockSupported ( VOID ) {- if (mVariableWriteLibVariableLock != NULL) {+ if (mVariableWriteLibVariablePolicy != NULL) { return TRUE; } else { return FALSE;@@ -178,16 +180,45 @@ VarLibVariableRequestToLock ( { EFI_STATUS Status = EFI_UNSUPPORTED; - if (mVariableWriteLibVariableLock != NULL) {- Status = mVariableWriteLibVariableLock->RequestToLock (- mVariableWriteLibVariableLock,- VariableName,- VendorGuid- );+ if (mVariableWriteLibVariablePolicy != NULL) {+ Status = RegisterBasicVariablePolicy (+ mVariableWriteLibVariablePolicy,+ (CONST EFI_GUID*) VendorGuid,+ (CONST CHAR16 *) VariableName,+ VARIABLE_POLICY_NO_MIN_SIZE,+ VARIABLE_POLICY_NO_MAX_SIZE,+ VARIABLE_POLICY_NO_MUST_ATTR,+ VARIABLE_POLICY_NO_CANT_ATTR,+ VARIABLE_POLICY_TYPE_LOCK_NOW+ ); } return Status; } +/**+ Close events when driver unloaded.++ @param[in] ImageHandle A handle for the image that is initializing this driver+ @param[in] SystemTable A pointer to the EFI system table++ @retval EFI_SUCCESS The initialization finished successfully.+**/+EFI_STATUS+EFIAPI+DxeRuntimeVariableWriteLibDestructor (+ IN EFI_HANDLE ImageHandle,+ IN EFI_SYSTEM_TABLE *SystemTable+ )+{+ if (mExitBootServiceEvent != 0) {+ gBS->CloseEvent (mExitBootServiceEvent);+ }+ if (mLegacyBootEvent != 0) {+ gBS->CloseEvent (mLegacyBootEvent);+ }+ return EFI_SUCCESS;+}+ /** Exit Boot Services Event notification handler. @@ -202,7 +233,7 @@ DxeRuntimeVariableWriteLibOnExitBootServices ( IN VOID *Context ) {- mVariableWriteLibVariableLock = NULL;+ mVariableWriteLibVariablePolicy = NULL; } /**@@ -227,13 +258,11 @@ DxeRuntimeVariableWriteLibConstructor ( ) { EFI_STATUS Status;- EFI_EVENT ExitBootServiceEvent;- EFI_EVENT LegacyBootEvent; // // Locate VariableLockProtocol. //- Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&mVariableWriteLibVariableLock);+ Status = gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, NULL, (VOID **)&mVariableWriteLibVariablePolicy); ASSERT_EFI_ERROR (Status); //@@ -245,7 +274,7 @@ DxeRuntimeVariableWriteLibConstructor ( DxeRuntimeVariableWriteLibOnExitBootServices, NULL, &gEfiEventExitBootServicesGuid,- &ExitBootServiceEvent+ &mExitBootServiceEvent ); ASSERT_EFI_ERROR (Status); @@ -257,7 +286,7 @@ DxeRuntimeVariableWriteLibConstructor ( TPL_NOTIFY, DxeRuntimeVariableWriteLibOnExitBootServices, NULL,- &LegacyBootEvent+ &mLegacyBootEvent ); ASSERT_EFI_ERROR (Status); diff --git a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf index e2dbd2fb49..61e85a6586 100644 --- a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf +++ b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemo +++ ryConfig.inf @@ -1,7 +1,7 @@ ### @file # Component information file for SaveMemoryConfig module #-# Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR>+# Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent #@@ -25,6 +25,7 @@ BaseMemoryLib LargeVariableReadLib LargeVariableWriteLib+ BaseLib [Packages] MdePkg/MdePkg.decdiff --git a/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h b/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h index c847d7f152..64b0090c2c 100644 --- a/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h +++ b/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLi +++ b.h @@ -16,7 +16,7 @@ is possible, adjusting the value of PcdMaxVariableSize may provide a simpler solution to this problem. - Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>+ Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/@@ -52,7 +52,7 @@ @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. @retval EFI_WRITE_PROTECTED The variable in question is read-only. @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted.-+ @retval EFI_ABORTED LockVariable was requested but failed. @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. **/@@ -66,4 +66,25 @@ SetLargeVariable ( IN VOID *Data ); +/**+ Locks the existing large variable.++ @param[in] VariableName A Null-terminated string that is the name of the vendor's variable.+ Each VariableName is unique for each VendorGuid. VariableName must+ contain 1 or more characters. If VariableName is an empty string,+ then EFI_INVALID_PARAMETER is returned.+ @param[in] VendorGuid A unique identifier for the vendor.+ @retval EFI_SUCCESS The firmware has successfully locked the variable.+ @retval EFI_INVALID_PARAMETER An invalid combination of variable name and GUID was supplied+ @retval EFI_UNSUPPORTED The service for locking variable is not ready.+ @retval EFI_NOT_FOUND The targeting variable for locking is not present.+ @retval EFI_ABORTED Fail to lock variable.+**/+EFI_STATUS+EFIAPI+LockLargeVariable (+ IN CHAR16 *VariableName,+ IN EFI_GUID *VendorGuid+ );+ #endif // _LARGE_VARIABLE_WRITE_LIB_H_diff --git a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf index 704a8ac7cc..f83090c847 100644 --- a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf +++ b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/D +++ xeRuntimeVariableWriteLib.inf @@ -10,7 +10,7 @@ # Using this library allows code to be written in a generic manner that can be # used in DXE or SMM without modification. #-# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>+# Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved.<BR> # # SPDX-License-Identifier: BSD-2-Clause-Patent #@@ -24,6 +24,7 @@ MODULE_TYPE = DXE_RUNTIME_DRIVER LIBRARY_CLASS = VariableWriteLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER CONSTRUCTOR = DxeRuntimeVariableWriteLibConstructor+ DESTRUCTOR = DxeRuntimeVariableWriteLibDestructor [Packages] MdePkg/MdePkg.dec@@ -37,13 +38,14 @@ UefiLib UefiBootServicesTableLib UefiRuntimeServicesTableLib+ VariablePolicyHelperLib [Guids] gEfiEventExitBootServicesGuid ## CONSUMES ## Event [Protocols] gEfiVariableWriteArchProtocolGuid ## CONSUMES- gEdkiiVariableLockProtocolGuid ## CONSUMES+ gEdkiiVariablePolicyProtocolGuid ## CONSUMES [Depex]- gEfiVariableWriteArchProtocolGuid AND gEdkiiVariableLockProtocolGuid+ gEfiVariableWriteArchProtocolGuid AND gEdkiiVariablePolicyProtocolGuid-- 2.28.0.windows.1 -=-=-=-=-=-= Groups.io Links: You receive all messages sent to this group. View/Reply Online (#86614): https://edk2.groups.io/g/devel/message/86614 Mute This Topic: https://groups.io/mt/89067146/1492418 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [isaac.w.oram@intel.com] -=-=-=-=-=-= ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [edk2-devel] [edk2-platforms: PATCH v3] MinPlatformPkg/SaveMemoryConfig: Variable may not be locked. 2022-02-12 0:47 ` [edk2-devel] " Oram, Isaac W @ 2022-02-14 0:26 ` Chiu, Chasel 0 siblings, 0 replies; 4+ messages in thread From: Chiu, Chasel @ 2022-02-14 0:26 UTC (permalink / raw) To: Oram, Isaac W, devel@edk2.groups.io Cc: Desimone, Nathaniel L, Gao, Liming, Dong, Eric Thanks Isaac! I will correct them when pushing the patch. > -----Original Message----- > From: Oram, Isaac W <isaac.w.oram@intel.com> > Sent: Saturday, February 12, 2022 8:48 AM > To: devel@edk2.groups.io; Chiu, Chasel <chasel.chiu@intel.com> > Cc: Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Gao, Liming > <gaoliming@byosoft.com.cn>; Dong, Eric <eric.dong@intel.com> > Subject: RE: [edk2-devel] [edk2-platforms: PATCH v3] > MinPlatformPkg/SaveMemoryConfig: Variable may not be locked. > > Reviewed-by: Isaac Oram <isaac.w.oram@intel.com> > > Minor code style nits that can be fixed before pushing: These do not need > another patch for review, if a maintainer agrees. > > SaveMemoryConfig.c > Line 95 : EFI_ERROR( put a space before ( Line 101, 118: CpuDeadLoop( put a > space before ( > > LargeVariableWriteLib.c: > Lines 506, 519, 542: EFI_ERROR( put a space before ( > > Regards, > Isaac > > -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Chiu, > Chasel > Sent: Friday, February 11, 2022 1:02 AM > To: devel@edk2.groups.io > Cc: Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L > <nathaniel.l.desimone@intel.com>; Gao, Liming > <gaoliming@byosoft.com.cn>; Dong, Eric <eric.dong@intel.com> > Subject: [edk2-devel] [edk2-platforms: PATCH v3] > MinPlatformPkg/SaveMemoryConfig: Variable may not be locked. > > From: "Chiu, Chasel" <chasel.chiu@intel.com> > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3829 > > Fixed the bug that existing variable will not be locked when it is identical with > hob data by creating LockLargeVariable function, also switched to > VariablePolicyProtocol for locking variables. > > Failing to lock variable could be security vulnerability, so the function will > return EFI_ABORTED when it failed and SaveMemoryConfig driver will halt > the system for developers to resolve this issue. > > This patch also modified SaveMemoryConfig driver to be unloaded after > execution because it does not produce any service protocol. To achieve this > goal the DxeRuntimeVariableWriteLib should close registered > ExitBootService events in its DESTRUCTOR. > > Cc: Nate DeSimone <nathaniel.l.desimone@intel.com> > Cc: Liming Gao <gaoliming@byosoft.com.cn> > Cc: Eric Dong <eric.dong@intel.com> > Signed-off-by: Chasel Chiu <chasel.chiu@intel.com> ---V3:Updated > LargeVariableWriteLib to return EFI_ABORTED when locking variables > failed.Also SaveMemoryConfig driver will halt the system in this case for > developers to fixsuch security vulnerability issue. > > Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMem > oryConfig.c | 27 ++++++++++++++++++++++++--- > > Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariable > WriteLib.c | 115 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++----- > > Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRu > ntimeVariableWriteLib.c | 61 > +++++++++++++++++++++++++++++++++++++++++++++---------------- > > Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMem > oryConfig.inf | 3 ++- > Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h > | 25 +++++++++++++++++++++++-- > > Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRu > ntimeVariableWriteLib.inf | 8 +++++--- > 6 files changed, 209 insertions(+), 30 deletions(-) > > diff --git > a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMe > moryConfig.c > b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMe > moryConfig.c > index 820585f676..54e11e20bd 100644 > --- > a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMe > moryConfig.c > +++ > b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMe > mo > +++ ryConfig.c > @@ -2,13 +2,14 @@ > This is the driver that locates the MemoryConfigurationData HOB, if it > exists, and saves the data to nvRAM. -Copyright (c) 2017 - 2021, Intel > Corporation. All rights reserved.<BR>+Copyright (c) 2017 - 2022, Intel > Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause- > Patent **/ #include <Base.h> #include <Uefi.h>+#include > <Library/BaseLib.h> #include <Library/UefiBootServicesTableLib.h> #include > <Library/UefiRuntimeServicesTableLib.h> #include <Library/HobLib.h>@@ - > 18,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > #include <Library/BaseMemoryLib.h> #include > <Library/LargeVariableReadLib.h> #include > <Library/LargeVariableWriteLib.h>+#include <Library/VariableWriteLib.h> > #include <Guid/FspNonVolatileStorageHob2.h> /**@@ -86,6 +88,18 @@ > SaveMemoryConfigEntryPoint ( > Status = GetLargeVariable (L"FspNvsBuffer", > &gFspNvsBufferVariableGuid, &BufferSize, VariableData); if > (!EFI_ERROR (Status) && (BufferSize == DataSize) && (0 == CompareMem > (HobData, VariableData, DataSize))) { DataIsIdentical = TRUE;+ > //+ // No need to update Variable, only lock it.+ //+ > Status = LockLargeVariable (L"FspNvsBuffer", > &gFspNvsBufferVariableGuid);+ if (EFI_ERROR(Status)) {+ //+ > // Fail to lock variable is security vulnerability and should not happen.+ > //+ DEBUG ((DEBUG_ERROR, "LockVariable is requested but failed > unexpectedly!\n"));+ ASSERT_EFI_ERROR (Status);+ > CpuDeadLoop();+ } } FreePool (VariableData); }@@ - > 96,6 +110,13 @@ SaveMemoryConfigEntryPoint ( > if (!DataIsIdentical) { Status = SetLargeVariable (L"FspNvsBuffer", > &gFspNvsBufferVariableGuid, TRUE, DataSize, HobData); > ASSERT_EFI_ERROR (Status);+ if (Status == EFI_ABORTED) {+ //+ > // Fail to lock variable is security vulnerability and should not happen.+ > //+ DEBUG ((DEBUG_ERROR, "LockVariable is requested but failed > unexpectedly!\n"));+ CpuDeadLoop();+ } DEBUG ((DEBUG_INFO, > "Saved size of FSP / MRC Training Data: 0x%x\n", DataSize)); } else > { DEBUG ((DEBUG_INFO, "FSP / MRC Training Data is identical to data > from last boot, no need to save.\n"));@@ -106,7 +127,7 @@ > SaveMemoryConfigEntryPoint ( > } //- // This driver cannot be unloaded because > DxeRuntimeVariableWriteLib constructor will register ExitBootServices > callback.+ // This driver does not produce any protocol services, so always > unload it. //- return EFI_SUCCESS;+ return > EFI_REQUEST_UNLOAD_IMAGE; }diff --git > a/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariabl > eWriteLib.c > b/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariabl > eWriteLib.c > index e4b97ef1df..154f6f448f 100644 > --- > a/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariabl > eWriteLib.c > +++ b/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVa > +++ riableWriteLib.c > @@ -10,7 +10,7 @@ > integer number will be added to the end of the variable name. This number > will be incremented for each variable as needed to store the entire data set. > - Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>+ Copyright > (c) 2021 - 2022, Intel Corporation. All rights reserved.<BR> SPDX-License- > Identifier: BSD-2-Clause-Patent **/@@ -245,7 +245,7 @@ Done: > @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a > hardware error. @retval EFI_WRITE_PROTECTED The variable in question is > read-only. @retval EFI_WRITE_PROTECTED The variable in question cannot > be deleted.-+ @retval EFI_ABORTED LockVariable was requested but > failed. @retval EFI_NOT_FOUND The variable trying to be updated or > deleted was not found. **/@@ -412,7 +412,7 @@ SetLargeVariable ( > // all data is saved. // if (LockVariable) {- for (Index = 0; Index < > VariablesSaved; Index++) {+ for (Index = 0; Index <= VariablesSaved; > Index++) { ZeroMem (TempVariableName, > MAX_VARIABLE_NAME_SIZE); UnicodeSPrint (TempVariableName, > MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index); @@ -420,7 > +420,7 @@ SetLargeVariable ( > Status = VarLibVariableRequestToLock (TempVariableName, > VendorGuid); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, > "SetLargeVariable: Error locking variable: Status = %r\n", Status));- > VariablesSaved = 0;+ Status = EFI_ABORTED; goto > Done; } }@@ -442,9 +442,114 @@ Done: > 0, NULL );- DEBUG ((DEBUG_ERROR, > "SetLargeVariable: Error deleting variable: Status = %r\n", Status2));+ if > (EFI_ERROR (Status2)) {+ DEBUG ((DEBUG_ERROR, "SetLargeVariable: > Error deleting variable: Status = %r\n", Status2));+ } } } DEBUG > ((DEBUG_ERROR, "SetLargeVariable: Status = %r\n", Status)); return > Status; }++/**+ Locks the existing large variable.++ @param[in] > VariableName A Null-terminated string that is the name of the vendor's > variable.+ Each VariableName is unique for each VendorGuid. > VariableName must+ contain 1 or more characters. If > VariableName is an empty string,+ then > EFI_INVALID_PARAMETER is returned.+ @param[in] VendorGuid A > unique identifier for the vendor.+ @retval EFI_SUCCESS The firmware > has successfully locked the variable.+ @retval EFI_INVALID_PARAMETER An > invalid combination of variable name and GUID was supplied+ @retval > EFI_UNSUPPORTED The service for locking variable is not ready.+ @retval > EFI_NOT_FOUND The targeting variable for locking is not present.+ > @retval EFI_ABORTED Fail to lock > variable.+**/+EFI_STATUS+EFIAPI+LockLargeVariable (+ IN CHAR16 > *VariableName,+ IN EFI_GUID *VendorGuid+ )+{+ CHAR16 > TempVariableName[MAX_VARIABLE_NAME_SIZE];+ UINT64 > VariableSize;+ EFI_STATUS Status;+ UINTN Index;++ //+ // Check > input parameters.+ //+ if (VariableName == NULL || VariableName[0] == 0 > || VendorGuid == NULL) {+ return EFI_INVALID_PARAMETER;+ }++ if > (!VarLibIsVariableRequestToLockSupported ()) {+ return > EFI_UNSUPPORTED;+ }++ VariableSize = 0;+ Index = 0;+ ZeroMem > (TempVariableName, MAX_VARIABLE_NAME_SIZE);+ UnicodeSPrint > (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, > Index);+ Status = VarLibGetVariable (TempVariableName, VendorGuid, > NULL, &VariableSize, NULL);+ if (Status == EFI_BUFFER_TOO_SMALL) {+ > //+ // Lock multiple variables.+ //++ //+ // Lock first variable and > continue to rest of the variables.+ //+ DEBUG ((DEBUG_INFO, "Locking %s, > Guid = %g\n", TempVariableName, VendorGuid));+ Status = > VarLibVariableRequestToLock (TempVariableName, VendorGuid);+ if > (EFI_ERROR(Status)) {+ DEBUG ((DEBUG_ERROR, "LockLargeVariable: > Failed! Satus = %r\n", Status));+ return EFI_ABORTED;+ }+ for (Index = 1; > Index < MAX_VARIABLE_SPLIT; Index++) {+ ZeroMem > (TempVariableName, MAX_VARIABLE_NAME_SIZE);+ UnicodeSPrint > (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, > Index);++ VariableSize = 0;+ Status = VarLibGetVariable > (TempVariableName, VendorGuid, NULL, &VariableSize, NULL);+ if (Status > == EFI_BUFFER_TOO_SMALL) {+ DEBUG ((DEBUG_INFO, "Locking %s, > Guid = %g\n", TempVariableName, VendorGuid));+ Status = > VarLibVariableRequestToLock (TempVariableName, VendorGuid);+ if > (EFI_ERROR(Status)) {+ DEBUG ((DEBUG_ERROR, "LockLargeVariable: > Failed! Satus = %r\n", Status));+ return EFI_ABORTED;+ }+ } else if > (Status == EFI_NOT_FOUND) {+ //+ // No more variables need to > lock.+ //+ return EFI_SUCCESS;+ }+ } // End of for loop+ } else if > (Status == EFI_NOT_FOUND) {+ //+ // Check if it is single variable > scenario.+ //+ VariableSize = 0;+ Status = VarLibGetVariable > (VariableName, VendorGuid, NULL, &VariableSize, NULL);+ if (Status == > EFI_BUFFER_TOO_SMALL) {+ //+ // Lock single variable.+ //+ > DEBUG ((DEBUG_INFO, "Locking %s, Guid = %g\n", VariableName, > VendorGuid));+ Status = VarLibVariableRequestToLock (VariableName, > VendorGuid);+ if (EFI_ERROR(Status)) {+ DEBUG ((DEBUG_ERROR, > "LockLargeVariable: Failed! Satus = %r\n", Status));+ return > EFI_ABORTED;+ }+ return EFI_SUCCESS;+ }+ }++ //+ // Here probably > means variable not present.+ //+ return Status;++}diff --git > a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/Dxe > RuntimeVariableWriteLib.c > b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/Dxe > RuntimeVariableWriteLib.c > index 9ed59f8827..28730f858b 100644 > --- > a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/Dxe > RuntimeVariableWriteLib.c > +++ > b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/D > +++ xeRuntimeVariableWriteLib.c > @@ -10,7 +10,7 @@ > Using this library allows code to be written in a generic manner that can be > used in DXE or SMM without modification. - Copyright (c) 2021, Intel > Corporation. All rights reserved.<BR>+ Copyright (c) 2021 - 2022, Intel > Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2- > Clause-Patent **/@@ -18,14 +18,16 @@ > #include <Uefi.h> #include <Guid/EventGroup.h>-#include > <Protocol/VariableLock.h>+#include <Library/VariablePolicyHelperLib.h> > #include <Library/UefiLib.h> #include <Library/DebugLib.h> #include > <Library/UefiBootServicesTableLib.h> #include > <Library/UefiRuntimeServicesTableLib.h> -STATIC > EDKII_VARIABLE_LOCK_PROTOCOL *mVariableWriteLibVariableLock = > NULL;+STATIC EDKII_VARIABLE_POLICY_PROTOCOL > *mVariableWriteLibVariablePolicy = NULL;+EFI_EVENT > mExitBootServiceEvent;+EFI_EVENT mLegacyBootEvent; /** > Sets the value of a variable.@@ -144,7 +146,7 @@ > VarLibIsVariableRequestToLockSupported ( > VOID ) {- if (mVariableWriteLibVariableLock != NULL) {+ if > (mVariableWriteLibVariablePolicy != NULL) { return TRUE; } else { return > FALSE;@@ -178,16 +180,45 @@ VarLibVariableRequestToLock ( > { EFI_STATUS Status = EFI_UNSUPPORTED; - if > (mVariableWriteLibVariableLock != NULL) {- Status = > mVariableWriteLibVariableLock->RequestToLock (- > mVariableWriteLibVariableLock,- VariableName,- > VendorGuid- );+ if > (mVariableWriteLibVariablePolicy != NULL) {+ Status = > RegisterBasicVariablePolicy (+ mVariableWriteLibVariablePolicy,+ > (CONST EFI_GUID*) VendorGuid,+ (CONST CHAR16 *) > VariableName,+ VARIABLE_POLICY_NO_MIN_SIZE,+ > VARIABLE_POLICY_NO_MAX_SIZE,+ > VARIABLE_POLICY_NO_MUST_ATTR,+ > VARIABLE_POLICY_NO_CANT_ATTR,+ > VARIABLE_POLICY_TYPE_LOCK_NOW+ ); } return Status; } +/**+ > Close events when driver unloaded.++ @param[in] ImageHandle A handle > for the image that is initializing this driver+ @param[in] SystemTable A > pointer to the EFI system table++ @retval EFI_SUCCESS The initialization > finished > successfully.+**/+EFI_STATUS+EFIAPI+DxeRuntimeVariableWriteLibDestruc > tor (+ IN EFI_HANDLE ImageHandle,+ IN EFI_SYSTEM_TABLE > *SystemTable+ )+{+ if (mExitBootServiceEvent != 0) {+ gBS->CloseEvent > (mExitBootServiceEvent);+ }+ if (mLegacyBootEvent != 0) {+ gBS- > >CloseEvent (mLegacyBootEvent);+ }+ return EFI_SUCCESS;+}+ /** Exit > Boot Services Event notification handler. @@ -202,7 +233,7 @@ > DxeRuntimeVariableWriteLibOnExitBootServices ( > IN VOID *Context ) {- mVariableWriteLibVariableLock = > NULL;+ mVariableWriteLibVariablePolicy = NULL; } /**@@ -227,13 +258,11 > @@ DxeRuntimeVariableWriteLibConstructor ( > ) { EFI_STATUS Status;- EFI_EVENT ExitBootServiceEvent;- EFI_EVENT > LegacyBootEvent; // // Locate VariableLockProtocol. //- Status = gBS- > >LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID > **)&mVariableWriteLibVariableLock);+ Status = gBS->LocateProtocol > (&gEdkiiVariablePolicyProtocolGuid, NULL, (VOID > **)&mVariableWriteLibVariablePolicy); ASSERT_EFI_ERROR (Status); > //@@ -245,7 +274,7 @@ DxeRuntimeVariableWriteLibConstructor ( > DxeRuntimeVariableWriteLibOnExitBootServices, NULL, > &gEfiEventExitBootServicesGuid,- &ExitBootServiceEvent+ > &mExitBootServiceEvent ); ASSERT_EFI_ERROR (Status); @@ -257,7 > +286,7 @@ DxeRuntimeVariableWriteLibConstructor ( > TPL_NOTIFY, DxeRuntimeVariableWriteLibOnExitBootServices, > NULL,- &LegacyBootEvent+ &mLegacyBootEvent ); > ASSERT_EFI_ERROR (Status); diff --git > a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMe > moryConfig.inf > b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMe > moryConfig.inf > index e2dbd2fb49..61e85a6586 100644 > --- > a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMe > moryConfig.inf > +++ > b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMe > mo > +++ ryConfig.inf > @@ -1,7 +1,7 @@ > ### @file # Component information file for SaveMemoryConfig module #-# > Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR>+# > Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.<BR> # # > SPDX-License-Identifier: BSD-2-Clause-Patent #@@ -25,6 +25,7 @@ > BaseMemoryLib LargeVariableReadLib LargeVariableWriteLib+ BaseLib > [Packages] MdePkg/MdePkg.decdiff --git > a/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h > b/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h > index c847d7f152..64b0090c2c 100644 > --- > a/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h > +++ b/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLi > +++ b.h > @@ -16,7 +16,7 @@ > is possible, adjusting the value of PcdMaxVariableSize may provide a > simpler solution to this problem. - Copyright (c) 2021, Intel Corporation. All > rights reserved.<BR>+ Copyright (c) 2021 - 2022, Intel Corporation. All rights > reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/@@ -52,7 > +52,7 @@ > @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a > hardware error. @retval EFI_WRITE_PROTECTED The variable in question is > read-only. @retval EFI_WRITE_PROTECTED The variable in question cannot > be deleted.-+ @retval EFI_ABORTED LockVariable was requested but > failed. @retval EFI_NOT_FOUND The variable trying to be updated or > deleted was not found. **/@@ -66,4 +66,25 @@ SetLargeVariable ( > IN VOID *Data ); +/**+ Locks the existing large variable.++ > @param[in] VariableName A Null-terminated string that is the name of > the vendor's variable.+ Each VariableName is unique for each > VendorGuid. VariableName must+ contain 1 or more > characters. If VariableName is an empty string,+ then > EFI_INVALID_PARAMETER is returned.+ @param[in] VendorGuid A > unique identifier for the vendor.+ @retval EFI_SUCCESS The firmware > has successfully locked the variable.+ @retval EFI_INVALID_PARAMETER An > invalid combination of variable name and GUID was supplied+ @retval > EFI_UNSUPPORTED The service for locking variable is not ready.+ @retval > EFI_NOT_FOUND The targeting variable for locking is not present.+ > @retval EFI_ABORTED Fail to lock > variable.+**/+EFI_STATUS+EFIAPI+LockLargeVariable (+ IN CHAR16 > *VariableName,+ IN EFI_GUID *VendorGuid+ );+ #endif // > _LARGE_VARIABLE_WRITE_LIB_H_diff --git > a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/Dxe > RuntimeVariableWriteLib.inf > b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/Dxe > RuntimeVariableWriteLib.inf > index 704a8ac7cc..f83090c847 100644 > --- > a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/Dxe > RuntimeVariableWriteLib.inf > +++ > b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/D > +++ xeRuntimeVariableWriteLib.inf > @@ -10,7 +10,7 @@ > # Using this library allows code to be written in a generic manner that can be > # used in DXE or SMM without modification. #-# Copyright (c) 2021, Intel > Corporation. All rights reserved.<BR>+# Copyright (c) 2021 - 2022, Intel > Corporation. All rights reserved.<BR> # # SPDX-License-Identifier: BSD-2- > Clause-Patent #@@ -24,6 +24,7 @@ > MODULE_TYPE = DXE_RUNTIME_DRIVER LIBRARY_CLASS > = VariableWriteLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER > UEFI_APPLICATION UEFI_DRIVER CONSTRUCTOR = > DxeRuntimeVariableWriteLibConstructor+ DESTRUCTOR = > DxeRuntimeVariableWriteLibDestructor [Packages] > MdePkg/MdePkg.dec@@ -37,13 +38,14 @@ > UefiLib UefiBootServicesTableLib UefiRuntimeServicesTableLib+ > VariablePolicyHelperLib [Guids] gEfiEventExitBootServicesGuid ## > CONSUMES ## Event [Protocols] gEfiVariableWriteArchProtocolGuid ## > CONSUMES- gEdkiiVariableLockProtocolGuid ## CONSUMES+ > gEdkiiVariablePolicyProtocolGuid ## CONSUMES [Depex]- > gEfiVariableWriteArchProtocolGuid AND gEdkiiVariableLockProtocolGuid+ > gEfiVariableWriteArchProtocolGuid AND gEdkiiVariablePolicyProtocolGuid-- > 2.28.0.windows.1 > > > > -=-=-=-=-=-= > Groups.io Links: You receive all messages sent to this group. > View/Reply Online (#86614): https://edk2.groups.io/g/devel/message/86614 > Mute This Topic: https://groups.io/mt/89067146/1492418 > Group Owner: devel+owner@edk2.groups.io > Unsubscribe: https://edk2.groups.io/g/devel/unsub > [isaac.w.oram@intel.com] -=-=-=-=-=-= > ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [edk2-platforms: PATCH v3] MinPlatformPkg/SaveMemoryConfig: Variable may not be locked. 2022-02-11 9:02 [edk2-platforms: PATCH v3] MinPlatformPkg/SaveMemoryConfig: Variable may not be locked Chiu, Chasel 2022-02-12 0:47 ` [edk2-devel] " Oram, Isaac W @ 2022-02-17 1:00 ` Nate DeSimone 1 sibling, 0 replies; 4+ messages in thread From: Nate DeSimone @ 2022-02-17 1:00 UTC (permalink / raw) To: Chiu, Chasel, devel@edk2.groups.io; +Cc: Gao, Liming, Dong, Eric Hi Chasel, Please see feedback inline. Thanks, Nate > -----Original Message----- > From: Chiu, Chasel <chasel.chiu@intel.com> > Sent: Friday, February 11, 2022 1:02 AM > To: devel@edk2.groups.io > Cc: Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L > <nathaniel.l.desimone@intel.com>; Gao, Liming > <gaoliming@byosoft.com.cn>; Dong, Eric <eric.dong@intel.com> > Subject: [edk2-platforms: PATCH v3] MinPlatformPkg/SaveMemoryConfig: > Variable may not be locked. > > From: "Chiu, Chasel" <chasel.chiu@intel.com> > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3829 > > Fixed the bug that existing variable will not be locked when it is > identical with hob data by creating LockLargeVariable function, also > switched to VariablePolicyProtocol for locking variables. > > Failing to lock variable could be security vulnerability, so the > function will return EFI_ABORTED when it failed and SaveMemoryConfig > driver will halt the system for developers to resolve this issue. > > This patch also modified SaveMemoryConfig driver to be unloaded after > execution because it does not produce any service protocol. To achieve > this goal the DxeRuntimeVariableWriteLib should close registered > ExitBootService events in its DESTRUCTOR. > > Cc: Nate DeSimone <nathaniel.l.desimone@intel.com> > Cc: Liming Gao <gaoliming@byosoft.com.cn> > Cc: Eric Dong <eric.dong@intel.com> > Signed-off-by: Chasel Chiu <chasel.chiu@intel.com> > --- > > > > V3: > > Updated LargeVariableWriteLib to return EFI_ABORTED when locking variables failed. > > Also SaveMemoryConfig driver will halt the system in this case for developers to fix > > such security vulnerability issue. > > > Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c | 27 ++++++++++++++++++++++++--- > Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariableWriteLib.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- > Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c | 61 +++++++++++++++++++++++++++++++++++++++++++++---------------- > Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf | 3 ++- > Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h | 25 +++++++++++++++++++++++-- > Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf | 8 +++++--- > 6 files changed, 209 insertions(+), 30 deletions(-) > > diff --git a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c > index 820585f676..54e11e20bd 100644 > --- a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c > +++ b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.c > @@ -2,13 +2,14 @@ > This is the driver that locates the MemoryConfigurationData HOB, if it > exists, and saves the data to nvRAM. > > -Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR> > +Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.<BR> > SPDX-License-Identifier: BSD-2-Clause-Patent > > **/ > > #include <Base.h> > #include <Uefi.h> > +#include <Library/BaseLib.h> > #include <Library/UefiBootServicesTableLib.h> > #include <Library/UefiRuntimeServicesTableLib.h> > #include <Library/HobLib.h> > @@ -18,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > #include <Library/BaseMemoryLib.h> > #include <Library/LargeVariableReadLib.h> > #include <Library/LargeVariableWriteLib.h> > +#include <Library/VariableWriteLib.h> > #include <Guid/FspNonVolatileStorageHob2.h> > > /** > @@ -86,6 +88,18 @@ SaveMemoryConfigEntryPoint ( > Status = GetLargeVariable (L"FspNvsBuffer", &gFspNvsBufferVariableGuid, &BufferSize, VariableData); > if (!EFI_ERROR (Status) && (BufferSize == DataSize) && (0 == CompareMem (HobData, VariableData, DataSize))) { > DataIsIdentical = TRUE; > + // > + // No need to update Variable, only lock it. > + // > + Status = LockLargeVariable (L"FspNvsBuffer", &gFspNvsBufferVariableGuid); > + if (EFI_ERROR(Status)) { > + // > + // Fail to lock variable is security vulnerability and should not happen. > + // > + DEBUG ((DEBUG_ERROR, "LockVariable is requested but failed unexpectedly!\n")); > + ASSERT_EFI_ERROR (Status); > + CpuDeadLoop(); A CpuDeadLoop() on release builds will cause failures on production systems. I understand the concern of a security vulnerability, but we should mitigate that by deleting the FspNvsBuffer variable if we are unable to lock it. Then we will re-run the full MRC during the next boot without security issue. > + } > } > FreePool (VariableData); > } > @@ -96,6 +110,13 @@ SaveMemoryConfigEntryPoint ( > if (!DataIsIdentical) { > Status = SetLargeVariable (L"FspNvsBuffer", &gFspNvsBufferVariableGuid, TRUE, DataSize, HobData); > ASSERT_EFI_ERROR (Status); > + if (Status == EFI_ABORTED) { > + // > + // Fail to lock variable is security vulnerability and should not happen. > + // > + DEBUG ((DEBUG_ERROR, "LockVariable is requested but failed unexpectedly!\n")); It would be a good idea to put an ASSERT_EFI_ERROR() here since the dead loop should be gone. > + CpuDeadLoop(); A CpuDeadLoop() on release builds will cause failures on production systems. I understand the concern of a security vulnerability, but we should mitigate that by deleting the FspNvsBuffer variable if we are unable to lock it. Then we will re-run the full MRC during the next boot without security issue. > + } > DEBUG ((DEBUG_INFO, "Saved size of FSP / MRC Training Data: 0x%x\n", DataSize)); > } else { > DEBUG ((DEBUG_INFO, "FSP / MRC Training Data is identical to data from last boot, no need to save.\n")); > @@ -106,7 +127,7 @@ SaveMemoryConfigEntryPoint ( > } > > // > - // This driver cannot be unloaded because DxeRuntimeVariableWriteLib constructor will register ExitBootServices callback. > + // This driver does not produce any protocol services, so always unload it. > // > - return EFI_SUCCESS; > + return EFI_REQUEST_UNLOAD_IMAGE; > } > diff --git a/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariableWriteLib.c b/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariableWriteLib.c > index e4b97ef1df..154f6f448f 100644 > --- a/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariableWriteLib.c > +++ b/Platform/Intel/MinPlatformPkg/Library/BaseLargeVariableLib/LargeVariableWriteLib.c > @@ -10,7 +10,7 @@ > integer number will be added to the end of the variable name. This number > will be incremented for each variable as needed to store the entire data set. > > - Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > + Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved.<BR> > SPDX-License-Identifier: BSD-2-Clause-Patent > > **/ > @@ -245,7 +245,7 @@ Done: > @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. > @retval EFI_WRITE_PROTECTED The variable in question is read-only. > @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted. > - > + @retval EFI_ABORTED LockVariable was requested but failed. > @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. > > **/ > @@ -412,7 +412,7 @@ SetLargeVariable ( > // all data is saved. > // > if (LockVariable) { > - for (Index = 0; Index < VariablesSaved; Index++) { > + for (Index = 0; Index <= VariablesSaved; Index++) { > ZeroMem (TempVariableName, MAX_VARIABLE_NAME_SIZE); > UnicodeSPrint (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index); > > @@ -420,7 +420,7 @@ SetLargeVariable ( > Status = VarLibVariableRequestToLock (TempVariableName, VendorGuid); > if (EFI_ERROR (Status)) { > DEBUG ((DEBUG_ERROR, "SetLargeVariable: Error locking variable: Status = %r\n", Status)); > - VariablesSaved = 0; > + Status = EFI_ABORTED; > goto Done; > } > } > @@ -442,9 +442,114 @@ Done: > 0, > NULL > ); > - DEBUG ((DEBUG_ERROR, "SetLargeVariable: Error deleting variable: Status = %r\n", Status2)); > + if (EFI_ERROR (Status2)) { > + DEBUG ((DEBUG_ERROR, "SetLargeVariable: Error deleting variable: Status = %r\n", Status2)); > + } > } > } > DEBUG ((DEBUG_ERROR, "SetLargeVariable: Status = %r\n", Status)); > return Status; > } > + > +/** > + Locks the existing large variable. > + > + @param[in] VariableName A Null-terminated string that is the name of the vendor's variable. > + Each VariableName is unique for each VendorGuid. VariableName must > + contain 1 or more characters. If VariableName is an empty string, > + then EFI_INVALID_PARAMETER is returned. > + @param[in] VendorGuid A unique identifier for the vendor. > + @retval EFI_SUCCESS The firmware has successfully locked the variable. > + @retval EFI_INVALID_PARAMETER An invalid combination of variable name and GUID was supplied > + @retval EFI_UNSUPPORTED The service for locking variable is not ready. > + @retval EFI_NOT_FOUND The targeting variable for locking is not present. > + @retval EFI_ABORTED Fail to lock variable. > +**/ > +EFI_STATUS > +EFIAPI > +LockLargeVariable ( > + IN CHAR16 *VariableName, > + IN EFI_GUID *VendorGuid > + ) > +{ > + CHAR16 TempVariableName[MAX_VARIABLE_NAME_SIZE]; > + UINT64 VariableSize; > + EFI_STATUS Status; > + UINTN Index; > + > + // > + // Check input parameters. > + // > + if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!VarLibIsVariableRequestToLockSupported ()) { > + return EFI_UNSUPPORTED; > + } > + You are missing a buffer overflow check here. Something like this: if (StrLen (VariableName) >= (MAX_VARIABLE_NAME_SIZE - MAX_VARIABLE_SPLIT_DIGITS)) { DEBUG ((DEBUG_ERROR, "LockLargeVariable: Variable name too long\n")); Status = EFI_OUT_OF_RESOURCES; goto Done; } > + VariableSize = 0; > + Index = 0; > + ZeroMem (TempVariableName, MAX_VARIABLE_NAME_SIZE); > + UnicodeSPrint (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index); > + Status = VarLibGetVariable (TempVariableName, VendorGuid, NULL, &VariableSize, NULL); For performance reasons I think it would be best to check the single variable case first. Because the single variable case should be the most common one. > + if (Status == EFI_BUFFER_TOO_SMALL) { > + // > + // Lock multiple variables. > + // > + > + // > + // Lock first variable and continue to rest of the variables. > + // > + DEBUG ((DEBUG_INFO, "Locking %s, Guid = %g\n", TempVariableName, VendorGuid)); > + Status = VarLibVariableRequestToLock (TempVariableName, VendorGuid); > + if (EFI_ERROR(Status)) { > + DEBUG ((DEBUG_ERROR, "LockLargeVariable: Failed! Satus = %r\n", Status)); > + return EFI_ABORTED; > + } > + for (Index = 1; Index < MAX_VARIABLE_SPLIT; Index++) { > + ZeroMem (TempVariableName, MAX_VARIABLE_NAME_SIZE); > + UnicodeSPrint (TempVariableName, MAX_VARIABLE_NAME_SIZE, L"%s%d", VariableName, Index); > + > + VariableSize = 0; > + Status = VarLibGetVariable (TempVariableName, VendorGuid, NULL, &VariableSize, NULL); > + if (Status == EFI_BUFFER_TOO_SMALL) { > + DEBUG ((DEBUG_INFO, "Locking %s, Guid = %g\n", TempVariableName, VendorGuid)); > + Status = VarLibVariableRequestToLock (TempVariableName, VendorGuid); > + if (EFI_ERROR(Status)) { > + DEBUG ((DEBUG_ERROR, "LockLargeVariable: Failed! Satus = %r\n", Status)); > + return EFI_ABORTED; > + } > + } else if (Status == EFI_NOT_FOUND) { > + // > + // No more variables need to lock. > + // > + return EFI_SUCCESS; > + } > + } // End of for loop > + } else if (Status == EFI_NOT_FOUND) { > + // > + // Check if it is single variable scenario. > + // > + VariableSize = 0; > + Status = VarLibGetVariable (VariableName, VendorGuid, NULL, &VariableSize, NULL); > + if (Status == EFI_BUFFER_TOO_SMALL) { > + // > + // Lock single variable. > + // > + DEBUG ((DEBUG_INFO, "Locking %s, Guid = %g\n", VariableName, VendorGuid)); > + Status = VarLibVariableRequestToLock (VariableName, VendorGuid); > + if (EFI_ERROR(Status)) { > + DEBUG ((DEBUG_ERROR, "LockLargeVariable: Failed! Satus = %r\n", Status)); > + return EFI_ABORTED; > + } > + return EFI_SUCCESS; > + } > + } > + > + // > + // Here probably means variable not present. > + // > + return Status; > + > +} > diff --git a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c > index 9ed59f8827..28730f858b 100644 > --- a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c > +++ b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.c > @@ -10,7 +10,7 @@ > Using this library allows code to be written in a generic manner that can be > used in DXE or SMM without modification. > > - Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > + Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved.<BR> > SPDX-License-Identifier: BSD-2-Clause-Patent > > **/ > @@ -18,14 +18,16 @@ > #include <Uefi.h> > > #include <Guid/EventGroup.h> > -#include <Protocol/VariableLock.h> > +#include <Library/VariablePolicyHelperLib.h> > > #include <Library/UefiLib.h> > #include <Library/DebugLib.h> > #include <Library/UefiBootServicesTableLib.h> > #include <Library/UefiRuntimeServicesTableLib.h> > > -STATIC EDKII_VARIABLE_LOCK_PROTOCOL *mVariableWriteLibVariableLock = NULL; > +STATIC EDKII_VARIABLE_POLICY_PROTOCOL *mVariableWriteLibVariablePolicy = NULL; > +EFI_EVENT mExitBootServiceEvent; > +EFI_EVENT mLegacyBootEvent; > > /** > Sets the value of a variable. > @@ -144,7 +146,7 @@ VarLibIsVariableRequestToLockSupported ( > VOID > ) > { > - if (mVariableWriteLibVariableLock != NULL) { > + if (mVariableWriteLibVariablePolicy != NULL) { > return TRUE; > } else { > return FALSE; > @@ -178,16 +180,45 @@ VarLibVariableRequestToLock ( > { > EFI_STATUS Status = EFI_UNSUPPORTED; > > - if (mVariableWriteLibVariableLock != NULL) { > - Status = mVariableWriteLibVariableLock->RequestToLock ( > - mVariableWriteLibVariableLock, > - VariableName, > - VendorGuid > - ); > + if (mVariableWriteLibVariablePolicy != NULL) { > + Status = RegisterBasicVariablePolicy ( > + mVariableWriteLibVariablePolicy, > + (CONST EFI_GUID*) VendorGuid, > + (CONST CHAR16 *) VariableName, > + VARIABLE_POLICY_NO_MIN_SIZE, > + VARIABLE_POLICY_NO_MAX_SIZE, > + VARIABLE_POLICY_NO_MUST_ATTR, > + VARIABLE_POLICY_NO_CANT_ATTR, > + VARIABLE_POLICY_TYPE_LOCK_NOW > + ); > } > return Status; > } > > +/** > + Close events when driver unloaded. > + > + @param[in] ImageHandle A handle for the image that is initializing this driver > + @param[in] SystemTable A pointer to the EFI system table > + > + @retval EFI_SUCCESS The initialization finished successfully. > +**/ > +EFI_STATUS > +EFIAPI > +DxeRuntimeVariableWriteLibDestructor ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + if (mExitBootServiceEvent != 0) { > + gBS->CloseEvent (mExitBootServiceEvent); > + } > + if (mLegacyBootEvent != 0) { > + gBS->CloseEvent (mLegacyBootEvent); > + } > + return EFI_SUCCESS; > +} > + > /** > Exit Boot Services Event notification handler. > > @@ -202,7 +233,7 @@ DxeRuntimeVariableWriteLibOnExitBootServices ( > IN VOID *Context > ) > { > - mVariableWriteLibVariableLock = NULL; > + mVariableWriteLibVariablePolicy = NULL; > } > > /** > @@ -227,13 +258,11 @@ DxeRuntimeVariableWriteLibConstructor ( > ) > { > EFI_STATUS Status; > - EFI_EVENT ExitBootServiceEvent; > - EFI_EVENT LegacyBootEvent; > > // > // Locate VariableLockProtocol. > // > - Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&mVariableWriteLibVariableLock); > + Status = gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, NULL, (VOID **)&mVariableWriteLibVariablePolicy); > ASSERT_EFI_ERROR (Status); > > // > @@ -245,7 +274,7 @@ DxeRuntimeVariableWriteLibConstructor ( > DxeRuntimeVariableWriteLibOnExitBootServices, > NULL, > &gEfiEventExitBootServicesGuid, > - &ExitBootServiceEvent > + &mExitBootServiceEvent > ); > ASSERT_EFI_ERROR (Status); > > @@ -257,7 +286,7 @@ DxeRuntimeVariableWriteLibConstructor ( > TPL_NOTIFY, > DxeRuntimeVariableWriteLibOnExitBootServices, > NULL, > - &LegacyBootEvent > + &mLegacyBootEvent > ); > ASSERT_EFI_ERROR (Status); > > diff --git a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf > index e2dbd2fb49..61e85a6586 100644 > --- a/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf > +++ b/Platform/Intel/MinPlatformPkg/FspWrapper/SaveMemoryConfig/SaveMemoryConfig.inf > @@ -1,7 +1,7 @@ > ### @file > # Component information file for SaveMemoryConfig module > # > -# Copyright (c) 2017 - 2021, Intel Corporation. All rights reserved.<BR> > +# Copyright (c) 2017 - 2022, Intel Corporation. All rights reserved.<BR> > # > # SPDX-License-Identifier: BSD-2-Clause-Patent > # > @@ -25,6 +25,7 @@ > BaseMemoryLib > LargeVariableReadLib > LargeVariableWriteLib > + BaseLib > > [Packages] > MdePkg/MdePkg.dec > diff --git a/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h b/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h > index c847d7f152..64b0090c2c 100644 > --- a/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h > +++ b/Platform/Intel/MinPlatformPkg/Include/Library/LargeVariableWriteLib.h > @@ -16,7 +16,7 @@ > is possible, adjusting the value of PcdMaxVariableSize may provide a simpler > solution to this problem. > > - Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > + Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved.<BR> > SPDX-License-Identifier: BSD-2-Clause-Patent > > **/ > @@ -52,7 +52,7 @@ > @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. > @retval EFI_WRITE_PROTECTED The variable in question is read-only. > @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted. > - > + @retval EFI_ABORTED LockVariable was requested but failed. > @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. > > **/ > @@ -66,4 +66,25 @@ SetLargeVariable ( > IN VOID *Data > ); > > +/** > + Locks the existing large variable. > + > + @param[in] VariableName A Null-terminated string that is the name of the vendor's variable. > + Each VariableName is unique for each VendorGuid. VariableName must > + contain 1 or more characters. If VariableName is an empty string, > + then EFI_INVALID_PARAMETER is returned. > + @param[in] VendorGuid A unique identifier for the vendor. > + @retval EFI_SUCCESS The firmware has successfully locked the variable. > + @retval EFI_INVALID_PARAMETER An invalid combination of variable name and GUID was supplied > + @retval EFI_UNSUPPORTED The service for locking variable is not ready. > + @retval EFI_NOT_FOUND The targeting variable for locking is not present. > + @retval EFI_ABORTED Fail to lock variable. > +**/ > +EFI_STATUS > +EFIAPI > +LockLargeVariable ( > + IN CHAR16 *VariableName, > + IN EFI_GUID *VendorGuid > + ); > + > #endif // _LARGE_VARIABLE_WRITE_LIB_H_ > diff --git a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf > index 704a8ac7cc..f83090c847 100644 > --- a/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf > +++ b/Platform/Intel/MinPlatformPkg/Library/DxeRuntimeVariableWriteLib/DxeRuntimeVariableWriteLib.inf > @@ -10,7 +10,7 @@ > # Using this library allows code to be written in a generic manner that can be > # used in DXE or SMM without modification. > # > -# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > +# Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved.<BR> > # > # SPDX-License-Identifier: BSD-2-Clause-Patent > # > @@ -24,6 +24,7 @@ > MODULE_TYPE = DXE_RUNTIME_DRIVER > LIBRARY_CLASS = VariableWriteLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER > CONSTRUCTOR = DxeRuntimeVariableWriteLibConstructor > + DESTRUCTOR = DxeRuntimeVariableWriteLibDestructor > > [Packages] > MdePkg/MdePkg.dec > @@ -37,13 +38,14 @@ > UefiLib > UefiBootServicesTableLib > UefiRuntimeServicesTableLib > + VariablePolicyHelperLib > > [Guids] > gEfiEventExitBootServicesGuid ## CONSUMES ## Event > > [Protocols] > gEfiVariableWriteArchProtocolGuid ## CONSUMES > - gEdkiiVariableLockProtocolGuid ## CONSUMES > + gEdkiiVariablePolicyProtocolGuid ## CONSUMES > > [Depex] > - gEfiVariableWriteArchProtocolGuid AND gEdkiiVariableLockProtocolGuid > + gEfiVariableWriteArchProtocolGuid AND gEdkiiVariablePolicyProtocolGuid > -- > 2.28.0.windows.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-02-17 1:00 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-02-11 9:02 [edk2-platforms: PATCH v3] MinPlatformPkg/SaveMemoryConfig: Variable may not be locked Chiu, Chasel 2022-02-12 0:47 ` [edk2-devel] " Oram, Isaac W 2022-02-14 0:26 ` Chiu, Chasel 2022-02-17 1:00 ` Nate DeSimone
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox