diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c new file mode 100644 index 00000000..b2c2f199 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c @@ -0,0 +1,148 @@ +/** @file + TCG MOR (Memory Overwrite Request) Lock Control support (DXE version). + + This module clears MemoryOverwriteRequestControlLock variable to indicate + MOR lock control unsupported. + +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <PiDxe.h> +#include <Guid/MemoryOverwriteControl.h> +#include <IndustryStandard/MemoryOverwriteRequestControlLock.h> +#include <Library/DebugLib.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include "Variable.h" + +#include <Protocol/VariablePolicy.h> +#include <Library/VariablePolicyHelperLib.h> + +/** + This service is an MOR/MorLock checker handler for the SetVariable(). + + @param[in] VariableName the name of the vendor's variable, as a + Null-Terminated Unicode String + @param[in] VendorGuid Unify identifier for vendor. + @param[in] Attributes Attributes bitmask to set for the variable. + @param[in] DataSize The size in bytes of Data-Buffer. + @param[in] Data Point to the content of the variable. + + @retval EFI_SUCCESS The MOR/MorLock check pass, and Variable + driver can store the variable data. + @retval EFI_INVALID_PARAMETER The MOR/MorLock data or data size or + attributes is not allowed for MOR variable. + @retval EFI_ACCESS_DENIED The MOR/MorLock is locked. + @retval EFI_ALREADY_STARTED The MorLock variable is handled inside this + function. Variable driver can just return + EFI_SUCCESS. +**/ +EFI_STATUS +SetVariableCheckHandlerMor ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + // + // Just let it pass. No need provide protection for DXE version. + // + return EFI_SUCCESS; +} + +/** + Initialization for MOR Control Lock. + + @retval EFI_SUCCESS MorLock initialization success. + @return Others Some error occurs. +**/ +EFI_STATUS +MorLockInit ( + VOID + ) +{ + // + // Always clear variable to report unsupported to OS. + // The reason is that the DXE version is not proper to provide *protection*. + // BIOS should use SMM version variable driver to provide such capability. + // + VariableServiceSetVariable ( + MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME, + &gEfiMemoryOverwriteRequestControlLockGuid, + 0, // Attributes + 0, // DataSize + NULL // Data + ); + + // + // The MOR variable can effectively improve platform security only when the + // MorLock variable protects the MOR variable. In turn MorLock cannot be made + // secure without SMM support in the platform firmware (see above). + // + // Thus, delete the MOR variable, should it exist for any reason (some OSes + // are known to create MOR unintentionally, in an attempt to set it), then + // also lock the MOR variable, in order to prevent other modules from + // creating it. + // + VariableServiceSetVariable ( + MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, + &gEfiMemoryOverwriteControlDataGuid, + 0, // Attributes + 0, // DataSize + NULL // Data + ); + + return EFI_SUCCESS; +} + +/** + Delayed initialization for MOR Control Lock at EndOfDxe. + + This function performs any operations queued by MorLockInit(). +**/ +VOID +MorLockInitAtEndOfDxe ( + VOID + ) +{ + EFI_STATUS Status; + EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy; + + // First, we obviously need to locate the VariablePolicy protocol. + Status = gBS->LocateProtocol( &gEdkiiVariablePolicyProtocolGuid, NULL, (VOID**)&VariablePolicy ); + if (EFI_ERROR( Status )) { + DEBUG(( DEBUG_ERROR, "%a - Could not locate VariablePolicy protocol! %r\n", __FUNCTION__, Status )); + return; + } + + // If we're successful, go ahead and set the policies to protect the target variables. + Status = RegisterBasicVariablePolicy( VariablePolicy, + &gEfiMemoryOverwriteRequestControlLockGuid, + MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME, + 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 ); + if (EFI_ERROR( Status )) { + DEBUG(( DEBUG_ERROR, "%a - Could not lock variable %s! %r\n", __FUNCTION__, MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME, Status )); + } + Status = RegisterBasicVariablePolicy( VariablePolicy, + &gEfiMemoryOverwriteControlDataGuid, + MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, + 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 ); + if (EFI_ERROR( Status )) { + DEBUG(( DEBUG_ERROR, "%a - Could not lock variable %s! %r\n", __FUNCTION__, MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, Status )); + } + + return; +} |