Copyright (C) 2013, Red Hat, Inc.\r
Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<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) Microsoft Corporation.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "Variable.h"\r
\r
+#include <Protocol/VariablePolicy.h>\r
+#include <Library/VariablePolicyLib.h>\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ProtocolIsVariablePolicyEnabled (\r
+ OUT BOOLEAN *State\r
+ );\r
+\r
EFI_HANDLE mHandle = NULL;\r
EFI_EVENT mVirtualAddressChangeEvent = NULL;\r
-EFI_EVENT mFtwRegistration = NULL;\r
+VOID *mFtwRegistration = NULL;\r
VOID ***mVarCheckAddressPointer = NULL;\r
UINTN mVarCheckAddressPointerCount = 0;\r
EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock = { VariableLockRequestToLock };\r
+EDKII_VARIABLE_POLICY_PROTOCOL mVariablePolicyProtocol = { EDKII_VARIABLE_POLICY_PROTOCOL_REVISION,\r
+ DisableVariablePolicy,\r
+ ProtocolIsVariablePolicyEnabled,\r
+ RegisterVariablePolicy,\r
+ DumpVariablePolicy,\r
+ LockVariablePolicy };\r
EDKII_VAR_CHECK_PROTOCOL mVarCheck = { VarCheckRegisterSetVariableCheckHandler,\r
VarCheckVariablePropertySet,\r
VarCheckVariablePropertyGet };\r
{\r
UINTN Index;\r
\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetBlockSize);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetPhysicalAddress);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetAttributes);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->SetAttributes);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Read);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Write);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->EraseBlocks);\r
- EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance);\r
+ if (mVariableModuleGlobal->FvbInstance != NULL) {\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetBlockSize);\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetPhysicalAddress);\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetAttributes);\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->SetAttributes);\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Read);\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->Write);\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->EraseBlocks);\r
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance);\r
+ }\r
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLangCodes);\r
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->LangCodes);\r
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang);\r
VOID *Context\r
)\r
{\r
+ EFI_STATUS Status;\r
+\r
if (!mEndOfDxe) {\r
MorLockInitAtEndOfDxe ();\r
+\r
+ Status = LockVariablePolicy ();\r
+ ASSERT_EFI_ERROR (Status);\r
//\r
// Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID event is not signaled.\r
//\r
VOID *Context\r
)\r
{\r
+ EFI_STATUS Status;\r
+\r
DEBUG ((EFI_D_INFO, "[Variable]END_OF_DXE is signaled\n"));\r
MorLockInitAtEndOfDxe ();\r
+ Status = LockVariablePolicy ();\r
+ ASSERT_EFI_ERROR (Status);\r
mEndOfDxe = TRUE;\r
mVarCheckAddressPointer = VarCheckLibInitializeAtEndOfDxe (&mVarCheckAddressPointerCount);\r
//\r
gBS->CloseEvent (Event);\r
}\r
\r
+/**\r
+ Initializes variable write service for DXE.\r
+\r
+**/\r
+VOID\r
+VariableWriteServiceInitializeDxe (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = VariableWriteServiceInitialize ();\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status));\r
+ }\r
+\r
+ //\r
+ // Some Secure Boot Policy Var (SecureBoot, etc) updates following other\r
+ // Secure Boot Policy Variable change. Record their initial value.\r
+ //\r
+ RecordSecureBootPolicyVarData();\r
+\r
+ //\r
+ // Install the Variable Write Architectural protocol.\r
+ //\r
+ Status = gBS->InstallProtocolInterface (\r
+ &mHandle,\r
+ &gEfiVariableWriteArchProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
/**\r
Fault Tolerant Write protocol notification event handler.\r
\r
ASSERT (PcdGet32 (PcdFlashNvStorageVariableSize) <= FtwMaxBlockSize);\r
}\r
\r
+ NvStorageVariableBase = NV_STORAGE_VARIABLE_BASE;\r
+ VariableStoreBase = NvStorageVariableBase + mNvFvHeaderCache->HeaderLength;\r
+\r
+ //\r
+ // Let NonVolatileVariableBase point to flash variable store base directly after FTW ready.\r
+ //\r
+ mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase;\r
+\r
//\r
// Find the proper FVB protocol for variable.\r
//\r
- NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);\r
- if (NvStorageVariableBase == 0) {\r
- NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);\r
- }\r
Status = GetFvbInfoByAddress (NvStorageVariableBase, NULL, &FvbProtocol);\r
if (EFI_ERROR (Status)) {\r
return ;\r
//\r
// Mark the variable storage region of the FLASH as RUNTIME.\r
//\r
- VariableStoreBase = NvStorageVariableBase + mNvFvHeaderCache->HeaderLength;\r
VariableStoreLength = mNvVariableCache->Size;\r
BaseAddress = VariableStoreBase & (~EFI_PAGE_MASK);\r
Length = VariableStoreLength + (VariableStoreBase - BaseAddress);\r
}\r
}\r
\r
- Status = VariableWriteServiceInitialize ();\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status));\r
- }\r
-\r
//\r
- // Some Secure Boot Policy Var (SecureBoot, etc) updates following other\r
- // Secure Boot Policy Variable change. Record their initial value.\r
+ // Initializes variable write service after FTW was ready.\r
//\r
- RecordSecureBootPolicyVarData();\r
-\r
- //\r
- // Install the Variable Write Architectural protocol.\r
- //\r
- Status = gBS->InstallProtocolInterface (\r
- &mHandle,\r
- &gEfiVariableWriteArchProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
+ VariableWriteServiceInitializeDxe ();\r
\r
//\r
// Close the notify event to avoid install gEfiVariableWriteArchProtocolGuid again.\r
}\r
\r
\r
+/**\r
+ This API function returns whether or not the policy engine is\r
+ currently being enforced.\r
+\r
+ @param[out] State Pointer to a return value for whether the policy enforcement\r
+ is currently enabled.\r
+\r
+ @retval EFI_SUCCESS\r
+ @retval Others An error has prevented this command from completing.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ProtocolIsVariablePolicyEnabled (\r
+ OUT BOOLEAN *State\r
+ )\r
+{\r
+ *State = IsVariablePolicyEnabled ();\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
/**\r
Variable Driver main entry point. The Variable driver places the 4 EFI\r
runtime services in the EFI System Table and installs arch protocols\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
- //\r
- // Register FtwNotificationEvent () notify function.\r
- //\r
- EfiCreateProtocolNotifyEvent (\r
- &gEfiFaultTolerantWriteProtocolGuid,\r
- TPL_CALLBACK,\r
- FtwNotificationEvent,\r
- (VOID *)SystemTable,\r
- &mFtwRegistration\r
- );\r
+ if (!PcdGetBool (PcdEmuVariableNvModeEnable)) {\r
+ //\r
+ // Register FtwNotificationEvent () notify function.\r
+ //\r
+ EfiCreateProtocolNotifyEvent (\r
+ &gEfiFaultTolerantWriteProtocolGuid,\r
+ TPL_CALLBACK,\r
+ FtwNotificationEvent,\r
+ (VOID *)SystemTable,\r
+ &mFtwRegistration\r
+ );\r
+ } else {\r
+ //\r
+ // Emulated non-volatile variable mode does not depend on FVB and FTW.\r
+ //\r
+ VariableWriteServiceInitializeDxe ();\r
+ }\r
\r
Status = gBS->CreateEventEx (\r
EVT_NOTIFY_SIGNAL,\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ // Register and initialize the VariablePolicy engine.\r
+ Status = InitVariablePolicyLib (VariableServiceGetVariable);\r
+ ASSERT_EFI_ERROR (Status);\r
+ Status = VarCheckRegisterSetVariableCheckHandler (ValidateSetVariable);\r
+ ASSERT_EFI_ERROR (Status);\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &mHandle,\r
+ &gEdkiiVariablePolicyProtocolGuid,\r
+ &mVariablePolicyProtocol,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
return EFI_SUCCESS;\r
}\r
\r