From: "Dandan Bi" <dandan.bi@intel.com>
To: "devel@edk2.groups.io" <devel@edk2.groups.io>,
"bret@corthon.com" <bret@corthon.com>
Cc: "Wang, Jian J" <jian.j.wang@intel.com>,
"Wu, Hao A" <hao.a.wu@intel.com>,
"Gao, Liming" <liming.gao@intel.com>
Subject: Re: [edk2-devel] [PATCH v6 02/14] MdeModulePkg: Define the VariablePolicyLib
Date: Thu, 2 Jul 2020 02:13:30 +0000 [thread overview]
Message-ID: <BN6PR11MB1393421389F91E0633D430BBEA6D0@BN6PR11MB1393.namprd11.prod.outlook.com> (raw)
In-Reply-To: <20200623064104.1908-3-brbarkel@microsoft.com>
4 comments inline, please check.
Thanks,
Dandan
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bret
> Barkelew
> Sent: Tuesday, June 23, 2020 2:41 PM
> To: devel@edk2.groups.io
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Wu, Hao A <hao.a.wu@intel.com>;
> Gao, Liming <liming.gao@intel.com>
> Subject: [edk2-devel] [PATCH v6 02/14] MdeModulePkg: Define the
> VariablePolicyLib
>
> https://bugzilla.tianocore.org/show_bug.cgi?id=2522
>
> VariablePolicy is an updated interface to
> replace VarLock and VarCheckProtocol.
>
> Add the VariablePolicyLib library that implements
> the portable business logic for the VariablePolicy
> engine.
>
> Also add host-based CI test cases for the lib.
>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Hao A Wu <hao.a.wu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Bret Barkelew <brbarkel@microsoft.com>
> Signed-off-by: Bret Barkelew <brbarkel@microsoft.com>
> ---
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c
> | 46 +
>
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDx
> e.c | 85 +
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> | 816 +++++++
>
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePo
> licyUnitTest.c | 2436 ++++++++++++++++++++
> MdeModulePkg/Include/Library/VariablePolicyLib.h |
> 207 ++
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
> | 44 +
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni
> | 12 +
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
> | 51 +
>
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePo
> licyUnitTest.inf | 40 +
> MdeModulePkg/MdeModulePkg.dec | 3 +
> MdeModulePkg/MdeModulePkg.dsc | 5 +
> MdeModulePkg/Test/MdeModulePkgHostTest.dsc |
> 11 +
> 12 files changed, 3756 insertions(+)
>
> diff --git
> a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c
> new file mode 100644
> index 000000000000..ad2ee0b2fb8f
> --- /dev/null
> +++
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c
> @@ -0,0 +1,46 @@
> +/** @file -- VariablePolicyExtraInitNull.c
>
> +This file contains extra init and deinit routines that don't do anything
>
> +extra.
>
> +
>
> +Copyright (c) Microsoft Corporation.
>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#include <Library/UefiRuntimeServicesTableLib.h>
>
> +
>
> +
>
> +/**
>
> + An extra init hook that enables the RuntimeDxe library instance to
>
> + register VirtualAddress change callbacks. Among other things.
>
> +
>
> + @retval EFI_SUCCESS Everything is good. Continue with init.
>
> + @retval Others Uh... don't continue.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +VariablePolicyExtraInit (
>
> + VOID
>
> + )
>
> +{
>
> + // NULL implementation.
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +
>
> +/**
>
> + An extra deinit hook that enables the RuntimeDxe library instance to
>
> + register VirtualAddress change callbacks. Among other things.
>
> +
>
> + @retval EFI_SUCCESS Everything is good. Continue with deinit.
>
> + @retval Others Uh... don't continue.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +VariablePolicyExtraDeinit (
>
> + VOID
>
> + )
>
> +{
>
> + // NULL implementation.
>
> + return EFI_SUCCESS;
>
> +}
>
> diff --git
> a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeD
> xe.c
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntime
> Dxe.c
> new file mode 100644
> index 000000000000..3ca87048b14b
> --- /dev/null
> +++
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntime
> Dxe.c
> @@ -0,0 +1,85 @@
> +/** @file -- VariablePolicyExtraInitRuntimeDxe.c
>
> +This file contains extra init and deinit routines that register and unregister
>
> +VariableAddressChange callbacks.
>
> +
>
> +Copyright (c) Microsoft Corporation.
>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#include <Library/UefiBootServicesTableLib.h>
>
> +#include <Library/UefiRuntimeServicesTableLib.h>
>
> +
>
> +extern EFI_GET_VARIABLE mGetVariableHelper;
>
> +extern UINT8 *mPolicyTable;
>
> +STATIC BOOLEAN mIsVirtualAddrConverted;
>
> +STATIC EFI_EVENT mVariablePolicyLibVirtualAddressChangeEvent =
> NULL;
>
> +
>
> +/**
>
> + For the RuntimeDxe version of this lib, convert internal pointer addresses
> to virtual addresses.
>
> +
>
> + @param[in] Event Event whose notification function is being invoked.
>
> + @param[in] Context The pointer to the notification function's context,
> which
>
> + is implementation-dependent.
>
> +**/
>
> +STATIC
>
> +VOID
>
> +EFIAPI
>
> +VariablePolicyLibVirtualAddressCallback (
>
> + IN EFI_EVENT Event,
>
> + IN VOID *Context
>
> + )
>
> +{
>
> + gRT->ConvertPointer (0, (VOID **)&mPolicyTable);
>
> + gRT->ConvertPointer (0, (VOID **)&mGetVariableHelper);
>
> + mIsVirtualAddrConverted = TRUE;
>
> +}
>
> +
>
> +
>
> +/**
>
> + An extra init hook that enables the RuntimeDxe library instance to
>
> + register VirtualAddress change callbacks. Among other things.
>
> +
>
> + @retval EFI_SUCCESS Everything is good. Continue with init.
>
> + @retval Others Uh... don't continue.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +VariablePolicyExtraInit (
>
> + VOID
>
> + )
>
> +{
>
> + return gBS->CreateEventEx (EVT_NOTIFY_SIGNAL,
>
> + TPL_NOTIFY,
>
> + VariablePolicyLibVirtualAddressCallback,
>
> + NULL,
>
> + &gEfiEventVirtualAddressChangeGuid,
>
> + &mVariablePolicyLibVirtualAddressChangeEvent);
>
> +}
>
> +
>
> +
>
> +/**
>
> + An extra deinit hook that enables the RuntimeDxe library instance to
>
> + register VirtualAddress change callbacks. Among other things.
>
> +
>
> + @retval EFI_SUCCESS Everything is good. Continue with deinit.
>
> + @retval Others Uh... don't continue.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +VariablePolicyExtraDeinit (
>
> + VOID
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + Status = EFI_SUCCESS;
>
> + if (mIsVirtualAddrConverted) {
>
> + Status = gBS->CloseEvent
> (mVariablePolicyLibVirtualAddressChangeEvent);
>
> + }
>
> + else {
>
> + Status = EFI_SUCCESS;
>
> + }
>
> +
>
> + return Status;
>
> +}
>
> diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> new file mode 100644
> index 000000000000..84c794adaed9
> --- /dev/null
> +++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c
> @@ -0,0 +1,816 @@
> +/** @file -- VariablePolicyLib.c
>
> +Business logic for Variable Policy enforcement.
>
> +
>
> +Copyright (c) Microsoft Corporation.
>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#include <Uefi.h>
>
> +
>
> +#include <Library/SafeIntLib.h>
>
> +#include <Library/MemoryAllocationLib.h>
>
> +#include <Library/BaseMemoryLib.h>
>
> +#include <Library/DebugLib.h>
>
> +#include <Library/PcdLib.h>
>
> +
>
> +#include <Protocol/VariablePolicy.h>
>
> +#include <Library/VariablePolicyLib.h>
>
> +
>
> +
>
> +// IMPORTANT NOTE: This library is currently rife with multiple return
> statements
>
> +// for error handling. A refactor should remove these at some point.
>
> +
>
> +//
>
> +// This library was designed with advanced unit-test features.
>
> +// This define handles the configuration.
>
> +#ifdef INTERNAL_UNIT_TEST
>
> +#undef STATIC
>
> +#define STATIC // Nothing...
>
> +#endif
>
> +
>
> +// An abstracted GetVariable interface that enables configuration
> regardless of the environment.
>
> +EFI_GET_VARIABLE mGetVariableHelper = NULL;
>
> +
>
> +// Master switch to lock this entire interface. Does not stop enforcement,
>
> +// just prevents the configuration from being changed for the rest of the
> boot.
>
> +STATIC BOOLEAN mInterfaceLocked = FALSE;
>
> +
>
> +// Master switch to disable the entire interface for a single boot.
>
> +// This will disable all policy enforcement for the duration of the boot.
>
> +STATIC BOOLEAN mProtectionDisabled = FALSE;
>
> +
>
> +// Table to hold all the current policies.
>
> +UINT8 *mPolicyTable = NULL;
>
> +STATIC UINT32 mCurrentTableSize = 0;
>
> +STATIC UINT32 mCurrentTableUsage = 0;
>
> +STATIC UINT32 mCurrentTableCount = 0;
>
> +
>
> +#define POLICY_TABLE_STEP_SIZE 0x1000
>
> +
>
> +// NOTE: DO NOT USE THESE MACROS on any structure that has not been
> validated.
>
> +// Current table data has already been sanitized.
>
> +#define GET_NEXT_POLICY(CurPolicy)
> (VARIABLE_POLICY_ENTRY*)((UINT8*)CurPolicy + CurPolicy->Size)
>
> +#define GET_POLICY_NAME(CurPolicy) (CHAR16*)((UINTN)CurPolicy +
> CurPolicy->OffsetToName)
>
> +
>
> +#define MATCH_PRIORITY_EXACT 0
>
> +#define MATCH_PRIORITY_MAX MATCH_PRIORITY_EXACT
>
> +#define MATCH_PRIORITY_MIN MAX_UINT8
>
> +
>
> +// ExtraInit/ExtraDeinit functions allow RuntimeDxe to register
> VirtualAddress callbacks.
>
> +EFI_STATUS
>
> +VariablePolicyExtraInit (
>
> + VOID
>
> + );
>
> +
>
> +EFI_STATUS
>
> +VariablePolicyExtraDeinit (
>
> + VOID
>
> + );
1. [Dandan]: Please also add comments for above two functions.
Please also pay attention to the coding style issue in other files.
>
> +
>
> +
>
> +/**
>
> + This helper function determines whether the structure of an incoming
> policy
>
> + is valid and internally consistent.
>
> +
>
> + @param[in] NewPolicy Pointer to the incoming policy structure.
>
> +
>
> + @retval TRUE
>
> + @retval FALSE Pointer is NULL, size is wrong, strings are empty, or
>
> + substructures overlap.
>
> +
>
> +**/
>
> +STATIC
>
> +BOOLEAN
>
> +IsValidVariablePolicyStructure (
>
> + IN CONST VARIABLE_POLICY_ENTRY *NewPolicy
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + UINTN EntryEnd;
>
> + CHAR16 *CheckChar;
>
> + UINTN WildcardCount;
>
> +
>
> + // Sanitize some quick values.
>
> + if (NewPolicy == NULL || NewPolicy->Size == 0 ||
>
> + // Structure size should be at least as long as the minumum structure and
> a NULL string.
>
> + NewPolicy->Size < sizeof(VARIABLE_POLICY_ENTRY) ||
>
> + // Check for the known revision.
>
> + NewPolicy->Version != VARIABLE_POLICY_ENTRY_REVISION) {
>
> + return FALSE;
>
> + }
>
> +
>
> + // Calculate the theoretical end of the structure and make sure
>
> + // that the structure can fit in memory.
>
> + Status = SafeUintnAdd( (UINTN)NewPolicy, NewPolicy->Size, &EntryEnd );
>
> + if (EFI_ERROR( Status )) {
>
> + return FALSE;
>
> + }
>
> +
>
> + // Check for a valid Max Size.
>
> + if (NewPolicy->MaxSize == 0) {
>
> + return FALSE;
>
> + }
>
> +
>
> + // Check for the valid list of lock policies.
>
> + if (NewPolicy->LockPolicyType != VARIABLE_POLICY_TYPE_NO_LOCK &&
>
> + NewPolicy->LockPolicyType != VARIABLE_POLICY_TYPE_LOCK_NOW &&
>
> + NewPolicy->LockPolicyType !=
> VARIABLE_POLICY_TYPE_LOCK_ON_CREATE &&
>
> + NewPolicy->LockPolicyType !=
> VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE)
>
> + {
>
> + return FALSE;
>
> + }
>
> +
>
> + // If the policy type is VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE,
> make sure that the matching state variable Name
>
> + // terminates before the OffsetToName for the matching policy variable
> Name.
>
> + if (NewPolicy->LockPolicyType ==
> VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE) {
>
> + // Adjust CheckChar to the offset of the LockPolicy->Name.
>
> + Status = SafeUintnAdd( (UINTN)NewPolicy +
> sizeof(VARIABLE_POLICY_ENTRY),
>
> + sizeof(VARIABLE_LOCK_ON_VAR_STATE_POLICY),
>
> + (UINTN*)&CheckChar );
>
> + if (EFI_ERROR( Status ) || EntryEnd <= (UINTN)CheckChar) {
>
> + return FALSE;
>
> + }
>
> + while (*CheckChar != CHAR_NULL) {
>
> + if (EntryEnd <= (UINTN)CheckChar) {
>
> + return FALSE;
>
> + }
>
> + CheckChar++;
>
> + }
>
> + // At this point we should have either exeeded the structure or be
> pointing at the last char in LockPolicy->Name.
>
> + // We should check to make sure that the policy Name comes
> immediately after this charcter.
>
> + if ((UINTN)++CheckChar != (UINTN)NewPolicy + NewPolicy-
> >OffsetToName) {
>
> + return FALSE;
>
> + }
>
> + }
>
> + // If the policy type is any other value, make sure that the LockPolicy
> structure has a zero length.
>
> + else {
>
> + if (NewPolicy->OffsetToName != sizeof(VARIABLE_POLICY_ENTRY)) {
>
> + return FALSE;
>
> + }
>
> + }
>
> +
>
> + // Check to make sure that the name has a terminating character
>
> + // before the end of the structure.
>
> + // We've already checked that the name is within the bounds of the
> structure.
>
> + if (NewPolicy->Size != NewPolicy->OffsetToName) {
>
> + CheckChar = (CHAR16*)((UINTN)NewPolicy + NewPolicy-
> >OffsetToName);
>
> + WildcardCount = 0;
>
> + while (*CheckChar != CHAR_NULL) {
>
> + // Make sure there aren't excessive wildcards.
>
> + if (*CheckChar == '#') {
>
> + WildcardCount++;
>
> + if (WildcardCount > MATCH_PRIORITY_MIN) {
>
> + return FALSE;
>
> + }
>
> + }
>
> + // Make sure you're still within the bounds of the policy structure.
>
> + if (EntryEnd <= (UINTN)CheckChar) {
>
> + return FALSE;
>
> + }
>
> + CheckChar++;
>
> + }
>
> +
>
> + // Finally, we should be pointed at the very last character in Name, so we
> should be right
>
> + // up against the end of the structure.
>
> + if ((UINTN)++CheckChar != EntryEnd) {
>
> + return FALSE;
>
> + }
>
> + }
>
> +
>
> + return TRUE;
>
> +}
>
> +
>
> +
>
> +/**
>
> + This helper function evaluates a policy and determines whether it matches
> the target
>
> + variable. If matched, will also return a value corresponding to the priority
> of the match.
>
> +
>
> + The rules for "best match" are listed in the Variable Policy Spec.
>
> + Perfect name matches will return 0.
>
> + Single wildcard characters will return the number of wildcard characters.
>
> + Full namespaces will return MAX_UINT8.
>
> +
>
> + @param[in] EvalEntry Pointer to the policy entry being evaluated.
>
> + @param[in] VariableName Same as EFI_SET_VARIABLE.
>
> + @param[in] VendorGuid Same as EFI_SET_VARIABLE.
>
> + @param[out] MatchPriority [Optional] On finding a match, this value
> contains the priority of the match.
>
> + Lower number == higher priority. Only valid if a match found.
>
> +
>
> + @retval TRUE Current entry matches the target variable.
>
> + @retval FALSE Current entry does not match at all.
>
> +
>
> +**/
>
> +STATIC
>
> +BOOLEAN
>
> +EvaluatePolicyMatch (
>
> + IN CONST VARIABLE_POLICY_ENTRY *EvalEntry,
>
> + IN CONST CHAR16 *VariableName,
>
> + IN CONST EFI_GUID *VendorGuid,
>
> + OUT UINT8 *MatchPriority OPTIONAL
>
> + )
>
> +{
>
> + BOOLEAN Result;
>
> + CHAR16 *PolicyName;
>
> + UINT8 CalculatedPriority;
>
> + UINTN Index;
>
> +
>
> + Result = FALSE;
>
> + CalculatedPriority = MATCH_PRIORITY_EXACT;
>
> +
>
> + // Step 1: If the GUID doesn't match, we're done. No need to evaluate
> anything else.
>
> + if (!CompareGuid( &EvalEntry->Namespace, VendorGuid )) {
>
> + goto Exit;
>
> + }
>
> +
>
> + // If the GUID matches, check to see whether there is a Name associated
>
> + // with the policy. If not, this policy matches the entire namespace.
>
> + // Missing Name is indicated by size being equal to name.
>
> + if (EvalEntry->Size == EvalEntry->OffsetToName) {
>
> + CalculatedPriority = MATCH_PRIORITY_MIN;
>
> + Result = TRUE;
>
> + goto Exit;
>
> + }
>
> +
>
> + // Now that we know the name exists, get it.
>
> + PolicyName = GET_POLICY_NAME( EvalEntry );
>
> +
>
> + // Evaluate the name against the policy name and check for a match.
>
> + // Account for any wildcards.
>
> + Index = 0;
>
> + Result = TRUE;
>
> + // Keep going until the end of both strings.
>
> + while (PolicyName[Index] != CHAR_NULL || VariableName[Index] !=
> CHAR_NULL) {
>
> + // If we don't have a match...
>
> + if (PolicyName[Index] != VariableName[Index] || PolicyName[Index] ==
> '#') {
>
> + // If this is a numerical wildcard, we can consider
>
> + // it a match if we alter the priority.
>
> + if (PolicyName[Index] == L'#' &&
>
> + (L'0' <= VariableName[Index] && VariableName[Index] <= L'9')) {
>
> + if (CalculatedPriority < MATCH_PRIORITY_MIN) {
>
> + CalculatedPriority++;
>
> + }
>
> + }
>
> + // Otherwise, not a match.
>
> + else {
2. [Dandan]: About the coding style, could we make the" } " and "else {" at the same line? Which is aligned with current edk2 style.
>
> + Result = FALSE;
>
> + goto Exit;
>
> + }
>
> + }
>
> + Index++;
>
> + }
>
> +
>
> +Exit:
>
> + if (Result && MatchPriority != NULL) {
>
> + *MatchPriority = CalculatedPriority;
>
> + }
>
> + return Result;
>
> +}
>
> +
>
> +
>
> +/**
>
> + This helper function walks the current policy table and returns a pointer
>
> + to the best match, if any are found. Leverages EvaluatePolicyMatch() to
>
> + determine "best".
>
> +
>
> + @param[in] VariableName Same as EFI_SET_VARIABLE.
>
> + @param[in] VendorGuid Same as EFI_SET_VARIABLE.
>
> + @param[out] ReturnPriority [Optional] If pointer is provided, return the
>
> + priority of the match. Same as EvaluatePolicyMatch().
>
> + Only valid if a match is returned.
>
> +
>
> + @retval VARIABLE_POLICY_ENTRY* Best match that was found.
>
> + @retval NULL No match was found.
>
> +
>
> +**/
>
> +STATIC
>
> +VARIABLE_POLICY_ENTRY*
>
> +GetBestPolicyMatch (
>
> + IN CONST CHAR16 *VariableName,
>
> + IN CONST EFI_GUID *VendorGuid,
>
> + OUT UINT8 *ReturnPriority OPTIONAL
>
> + )
>
> +{
>
> + VARIABLE_POLICY_ENTRY *BestResult;
>
> + VARIABLE_POLICY_ENTRY *CurrentEntry;
>
> + UINT8 MatchPriority;
>
> + UINT8 CurrentPriority;
>
> + UINTN Index;
>
> +
>
> + BestResult = NULL;
>
> +
>
> + // Walk all entries in the table, looking for matches.
>
> + CurrentEntry = (VARIABLE_POLICY_ENTRY*)mPolicyTable;
>
> + for (Index = 0; Index < mCurrentTableCount; Index++) {
>
> + // Check for a match.
>
> + if (EvaluatePolicyMatch( CurrentEntry, VariableName, VendorGuid,
> &CurrentPriority )) {
>
> + // If match is better, take it.
>
> + if (BestResult == NULL || CurrentPriority < MatchPriority) {
3. [Dandan]: MatchPriority seems not be initialized but used here.
>
> + BestResult = CurrentEntry;
>
> + MatchPriority = CurrentPriority;
>
> + }
>
> +
>
> + // If you've hit the highest-priority match, can exit now.
>
> + if (MatchPriority == 0) {
>
> + break;
>
> + }
>
> + }
>
> +
>
> + // If we're still in the loop, move to the next entry.
>
> + CurrentEntry = GET_NEXT_POLICY( CurrentEntry );
>
> + }
>
> +
>
> + // If a return priority was requested, return it.
>
> + if (ReturnPriority != NULL) {
>
> + *ReturnPriority = MatchPriority;
>
> + }
>
> +
>
> + return BestResult;
>
> +}
>
> +
>
> +
>
> +/**
>
> + This API function validates and registers a new policy with
>
> + the policy enforcement engine.
>
> +
>
> + @param[in] NewPolicy Pointer to the incoming policy structure.
>
> +
>
> + @retval EFI_SUCCESS
>
> + @retval EFI_INVALID_PARAMETER NewPolicy is NULL or is internally
> inconsistent.
>
> + @retval EFI_ALREADY_STARTED An identical matching policy already
> exists.
>
> + @retval EFI_WRITE_PROTECTED The interface has been locked until
> the next reboot.
>
> + @retval EFI_UNSUPPORTED Policy enforcement has been disabled.
> No reason to add more policies.
>
> + @retval EFI_ABORTED A calculation error has prevented this
> function from completing.
>
> + @retval EFI_OUT_OF_RESOURCES Cannot grow the table to hold any
> more policies.
>
> + @retval EFI_NOT_READY Library has not yet been initialized.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +RegisterVariablePolicy (
>
> + IN CONST VARIABLE_POLICY_ENTRY *NewPolicy
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + VARIABLE_POLICY_ENTRY *MatchPolicy;
>
> + UINT8 MatchPriority;
>
> + UINT32 NewSize;
>
> + UINT8 *NewTable;
>
> +
>
> + if (!IsVariablePolicyLibInitialized()) {
>
> + return EFI_NOT_READY;
>
> + }
>
> + if (mInterfaceLocked) {
>
> + return EFI_WRITE_PROTECTED;
>
> + }
>
> +
>
> + if (!IsValidVariablePolicyStructure( NewPolicy )) {
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + // Check to see whether an exact matching policy already exists.
>
> + MatchPolicy = GetBestPolicyMatch( GET_POLICY_NAME( NewPolicy ),
>
> + &NewPolicy->Namespace,
>
> + &MatchPriority );
>
> + if (MatchPolicy != NULL && MatchPriority == MATCH_PRIORITY_EXACT) {
>
> + return EFI_ALREADY_STARTED;
>
> + }
>
> +
>
> + // If none exists, create it.
>
> + // If we need more space, allocate that now.
>
> + Status = SafeUint32Add( mCurrentTableUsage, NewPolicy->Size,
> &NewSize );
>
> + if (EFI_ERROR( Status )) {
>
> + return EFI_ABORTED;
>
> + }
>
> + if (NewSize > mCurrentTableSize) {
>
> + // Use NewSize to calculate the new table size in units of
> POLICY_TABLE_STEP_SIZE.
>
> + NewSize = (NewSize % POLICY_TABLE_STEP_SIZE) > 0 ?
>
> + (NewSize / POLICY_TABLE_STEP_SIZE) + 1 :
>
> + (NewSize / POLICY_TABLE_STEP_SIZE);
>
> + // Calculate the new table size in absolute bytes.
>
> + Status = SafeUint32Mult( NewSize, POLICY_TABLE_STEP_SIZE,
> &NewSize );
>
> + if (EFI_ERROR( Status )) {
>
> + return EFI_ABORTED;
>
> + }
>
> +
>
> + // Reallocate and copy the table.
>
> + NewTable = AllocatePool( NewSize );
>
> + if (NewTable == NULL) {
>
> + return EFI_OUT_OF_RESOURCES;
>
> + }
>
> + CopyMem( NewTable, mPolicyTable, mCurrentTableUsage );
>
> + mCurrentTableSize = NewSize;
>
> + if (mPolicyTable != NULL) {
>
> + FreePool( mPolicyTable );
>
> + }
>
> + mPolicyTable = NewTable;
>
> + }
>
> + // Copy the policy into the table.
>
> + CopyMem( mPolicyTable + mCurrentTableUsage, NewPolicy, NewPolicy-
> >Size );
>
> + mCurrentTableUsage += NewPolicy->Size;
>
> + mCurrentTableCount += 1;
>
> +
>
> + // We're done here.
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +
>
> +/**
>
> + This API function checks to see whether the parameters to SetVariable
> would
>
> + be allowed according to the current variable policies.
>
> +
>
> + @param[in] VariableName Same as EFI_SET_VARIABLE.
>
> + @param[in] VendorGuid Same as EFI_SET_VARIABLE.
>
> + @param[in] Attributes Same as EFI_SET_VARIABLE.
>
> + @param[in] DataSize Same as EFI_SET_VARIABLE.
>
> + @param[in] Data Same as EFI_SET_VARIABLE.
>
> +
>
> + @retval EFI_SUCCESS A matching policy allows this update.
>
> + @retval EFI_SUCCESS There are currently no policies that restrict
> this update.
>
> + @retval EFI_SUCCESS The protections have been disable until the
> next reboot.
>
> + @retval EFI_WRITE_PROTECTED Variable is currently locked.
>
> + @retval EFI_INVALID_PARAMETER Attributes or size are invalid.
>
> + @retval EFI_ABORTED A lock policy exists, but an error prevented
> evaluation.
>
> + @retval EFI_NOT_READY Library has not been initialized.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +ValidateSetVariable (
>
> + IN CHAR16 *VariableName,
>
> + IN EFI_GUID *VendorGuid,
>
> + IN UINT32 Attributes,
>
> + IN UINTN DataSize,
>
> + IN VOID *Data
>
> + )
>
> +{
>
> + BOOLEAN IsDel;
>
> + VARIABLE_POLICY_ENTRY *ActivePolicy;
>
> + EFI_STATUS Status;
>
> + EFI_STATUS ReturnStatus;
>
> + VARIABLE_LOCK_ON_VAR_STATE_POLICY *StateVarPolicy;
>
> + CHAR16 *StateVarName;
>
> + UINTN StateVarSize;
>
> + UINT8 StateVar;
>
> +
>
> + ReturnStatus = EFI_SUCCESS;
>
> +
>
> + if (!IsVariablePolicyLibInitialized()) {
>
> + ReturnStatus = EFI_NOT_READY;
>
> + goto Exit;
>
> + }
>
> +
>
> + // Bail if the protections are currently disabled.
>
> + if (mProtectionDisabled) {
>
> + ReturnStatus = EFI_SUCCESS;
>
> + goto Exit;
>
> + }
>
> +
>
> + // Determine whether this is a delete operation.
>
> + // If so, it will affect which tests are applied.
>
> + if ((DataSize == 0) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0))
> {
>
> + IsDel = TRUE;
>
> + }
>
> + else {
>
> + IsDel = FALSE;
>
> + }
>
> +
>
> + // Find an active policy if one exists.
>
> + ActivePolicy = GetBestPolicyMatch( VariableName, VendorGuid, NULL );
>
> +
>
> + // If we have an active policy, check it against the incoming data.
>
> + if (ActivePolicy != NULL) {
>
> + //
>
> + // Only enforce size and attribute constraints when updating data, not
> deleting.
>
> + if (!IsDel) {
>
> + // Check for size constraints.
>
> + if ((ActivePolicy->MinSize > 0 && DataSize < ActivePolicy->MinSize) ||
>
> + (ActivePolicy->MaxSize > 0 && DataSize > ActivePolicy->MaxSize)) {
>
> + ReturnStatus = EFI_INVALID_PARAMETER;
>
> + DEBUG(( DEBUG_VERBOSE, "%a - Bad Size. 0x%X <> 0x%X-0x%X\n",
> __FUNCTION__,
>
> + DataSize, ActivePolicy->MinSize, ActivePolicy->MaxSize ));
>
> + goto Exit;
>
> + }
>
> +
>
> + // Check for attribute constraints.
>
> + if ((ActivePolicy->AttributesMustHave & Attributes) != ActivePolicy-
> >AttributesMustHave ||
>
> + (ActivePolicy->AttributesCantHave & Attributes) != 0) {
>
> + ReturnStatus = EFI_INVALID_PARAMETER;
>
> + DEBUG(( DEBUG_VERBOSE, "%a - Bad Attributes. 0x%X <>
> 0x%X:0x%X\n", __FUNCTION__,
>
> + Attributes, ActivePolicy->AttributesMustHave, ActivePolicy-
> >AttributesCantHave ));
>
> + goto Exit;
>
> + }
>
> + }
>
> +
>
> + //
>
> + // Lock policy check.
>
> + //
>
> + // Check for immediate lock.
>
> + if (ActivePolicy->LockPolicyType == VARIABLE_POLICY_TYPE_LOCK_NOW)
> {
>
> + ReturnStatus = EFI_WRITE_PROTECTED;
>
> + goto Exit;
>
> + }
>
> + // Check for lock on create.
>
> + else if (ActivePolicy->LockPolicyType ==
> VARIABLE_POLICY_TYPE_LOCK_ON_CREATE) {
>
> + StateVarSize = 0;
>
> + Status = mGetVariableHelper( VariableName,
>
> + VendorGuid,
>
> + NULL,
>
> + &StateVarSize,
>
> + NULL );
>
> + if (Status == EFI_BUFFER_TOO_SMALL) {
>
> + ReturnStatus = EFI_WRITE_PROTECTED;
>
> + goto Exit;
>
> + }
>
> + }
>
> + // Check for lock on state variable.
>
> + else if (ActivePolicy->LockPolicyType ==
> VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE) {
>
> + StateVarPolicy =
> (VARIABLE_LOCK_ON_VAR_STATE_POLICY*)((UINT8*)ActivePolicy +
> sizeof(VARIABLE_POLICY_ENTRY));
>
> + StateVarName = (CHAR16*)((UINT8*)StateVarPolicy +
> sizeof(VARIABLE_LOCK_ON_VAR_STATE_POLICY));
>
> + StateVarSize = sizeof(StateVar);
>
> + Status = mGetVariableHelper( StateVarName,
>
> + &StateVarPolicy->Namespace,
>
> + NULL,
>
> + &StateVarSize,
>
> + &StateVar );
>
> +
>
> + // If the variable was found, check the state. If matched, this variable is
> locked.
>
> + if (!EFI_ERROR( Status )) {
>
> + if (StateVar == StateVarPolicy->Value) {
>
> + ReturnStatus = EFI_WRITE_PROTECTED;
>
> + goto Exit;
>
> + }
>
> + }
>
> + // EFI_NOT_FOUND and EFI_BUFFER_TOO_SMALL indicate that the
> state doesn't match.
>
> + else if (Status != EFI_NOT_FOUND && Status !=
> EFI_BUFFER_TOO_SMALL) {
>
> + // We don't know what happened, but it isn't good.
>
> + ReturnStatus = EFI_ABORTED;
>
> + goto Exit;
>
> + }
>
> + }
>
> + }
>
> +
>
> +Exit:
>
> + DEBUG(( DEBUG_VERBOSE, "%a - Variable (%g:%s) returning %r.\n",
> __FUNCTION__, VendorGuid, VariableName, ReturnStatus ));
>
> + return ReturnStatus;
>
> +}
>
> +
>
> +
>
> +/**
>
> + This API function disables the variable policy enforcement. If it's
>
> + already been called once, will return EFI_ALREADY_STARTED.
>
> +
>
> + @retval EFI_SUCCESS
>
> + @retval EFI_ALREADY_STARTED Has already been called once this boot.
>
> + @retval EFI_WRITE_PROTECTED Interface has been locked until reboot.
>
> + @retval EFI_WRITE_PROTECTED Interface option is disabled by platform
> PCD.
>
> + @retval EFI_NOT_READY Library has not yet been initialized.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +DisableVariablePolicy (
>
> + VOID
>
> + )
>
> +{
>
> + if (!IsVariablePolicyLibInitialized()) {
>
> + return EFI_NOT_READY;
>
> + }
>
> + if (mProtectionDisabled) {
>
> + return EFI_ALREADY_STARTED;
>
> + }
>
> + if (mInterfaceLocked) {
>
> + return EFI_WRITE_PROTECTED;
>
> + }
>
> + if (!PcdGetBool (PcdAllowVariablePolicyEnforcementDisable)) {
>
> + return EFI_WRITE_PROTECTED;
>
> + }
>
> + mProtectionDisabled = TRUE;
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +
>
> +/**
>
> + This API function will dump the entire contents of the variable policy table.
>
> +
>
> + Similar to GetVariable, the first call can be made with a 0 size and it will
> return
>
> + the size of the buffer required to hold the entire table.
>
> +
>
> + @param[out] Policy Pointer to the policy buffer. Can be NULL if Size is 0.
>
> + @param[in,out] Size On input, the size of the output buffer. On output,
> the size
>
> + of the data returned.
>
> +
>
> + @retval EFI_SUCCESS Policy data is in the output buffer and Size
> has been updated.
>
> + @retval EFI_INVALID_PARAMETER Size is NULL, or Size is non-zero and
> Policy is NULL.
>
> + @retval EFI_BUFFER_TOO_SMALL Size is insufficient to hold policy. Size
> updated with required size.
>
> + @retval EFI_NOT_READY Library has not yet been initialized.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +DumpVariablePolicy (
>
> + OUT UINT8 *Policy,
>
> + IN OUT UINT32 *Size
>
> + )
>
> +{
>
> + if (!IsVariablePolicyLibInitialized()) {
>
> + return EFI_NOT_READY;
>
> + }
>
> +
>
> + // Check the parameters.
>
> + if (Size == NULL || (*Size > 0 && Policy == NULL)) {
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + // Make sure the size is sufficient to hold the policy table.
>
> + if (*Size < mCurrentTableUsage) {
>
> + *Size = mCurrentTableUsage;
>
> + return EFI_BUFFER_TOO_SMALL;
>
> + }
>
> +
>
> + // If we're still here, copy the table and bounce.
>
> + CopyMem( Policy, mPolicyTable, mCurrentTableUsage );
>
> + *Size = mCurrentTableUsage;
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +
>
> +/**
>
> + This API function returns whether or not the policy engine is
>
> + currently being enforced.
>
> +
>
> + @retval TRUE
>
> + @retval FALSE
>
> + @retval FALSE Library has not yet been initialized.
>
> +
>
> +**/
>
> +BOOLEAN
>
> +EFIAPI
>
> +IsVariablePolicyEnabled (
>
> + VOID
>
> + )
>
> +{
>
> + if (!IsVariablePolicyLibInitialized()) {
>
> + return FALSE;
>
> + }
>
> + return !mProtectionDisabled;
>
> +}
>
> +
>
> +
>
> +/**
>
> + This API function locks the interface so that no more policy updates
>
> + can be performed or changes made to the enforcement until the next
> boot.
>
> +
>
> + @retval EFI_SUCCESS
>
> + @retval EFI_NOT_READY Library has not yet been initialized.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +LockVariablePolicy (
>
> + VOID
>
> + )
>
> +{
>
> + if (!IsVariablePolicyLibInitialized()) {
>
> + return EFI_NOT_READY;
>
> + }
>
> + if (mInterfaceLocked) {
>
> + return EFI_WRITE_PROTECTED;
>
> + }
>
> + mInterfaceLocked = TRUE;
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +
>
> +/**
>
> + This API function returns whether or not the policy interface is locked
>
> + for the remainder of the boot.
>
> +
>
> + @retval TRUE
>
> + @retval FALSE
>
> + @retval FALSE Library has not yet been initialized.
>
> +
>
> +**/
>
> +BOOLEAN
>
> +EFIAPI
>
> +IsVariablePolicyInterfaceLocked (
>
> + VOID
>
> + )
>
> +{
>
> + if (!IsVariablePolicyLibInitialized()) {
>
> + return FALSE;
>
> + }
>
> + return mInterfaceLocked;
>
> +}
>
> +
>
> +
>
> +/**
>
> + This helper function initializes the library and sets
>
> + up any required internal structures or handlers.
>
> +
>
> + Also registers the internal pointer for the GetVariable helper.
>
> +
>
> + @param[in] GetVariableHelper A function pointer matching the
> EFI_GET_VARIABLE prototype that will be used to
>
> + check policy criteria that involve the existence of other variables.
>
> +
>
> + @retval EFI_SUCCESS
>
> + @retval EFI_ALREADY_STARTED The initialize function has been called
> more than once without a call to
>
> + deinitialize.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +InitVariablePolicyLib (
>
> + IN EFI_GET_VARIABLE GetVariableHelper
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + Status = EFI_SUCCESS;
>
> + if (mGetVariableHelper != NULL) {
>
> + Status = EFI_ALREADY_STARTED;
4. [Dandan]: Could we return directly here?
>
> + }
>
> +
>
> + if (!EFI_ERROR( Status )) {
>
> + Status = VariablePolicyExtraInit();
>
> + }
>
> +
>
> + if (!EFI_ERROR( Status )) {
>
> + // Save an internal pointer to the GetVariableHelper.
>
> + mGetVariableHelper = GetVariableHelper;
>
> +
>
> + // Initialize the global state.
>
> + mInterfaceLocked = FALSE;
>
> + mProtectionDisabled = FALSE;
>
> + mPolicyTable = NULL;
>
> + mCurrentTableSize = 0;
>
> + mCurrentTableUsage = 0;
>
> + mCurrentTableCount = 0;
>
> + }
>
> +
>
> + return Status;
>
> +}
>
> +
>
> +
>
> +/**
>
> + This helper function returns whether or not the library is currently
> initialized.
>
> +
>
> + @retval TRUE
>
> + @retval FALSE
>
> +
>
> +**/
>
> +BOOLEAN
>
> +EFIAPI
>
> +IsVariablePolicyLibInitialized (
>
> + VOID
>
> + )
>
> +{
>
> + return (mGetVariableHelper != NULL);
>
> +}
>
> +
>
> +
>
> +/**
>
> + This helper function tears down the library.
>
> +
>
> + Should generally only be used for test harnesses.
>
> +
>
> + @retval EFI_SUCCESS
>
> + @retval EFI_NOT_READY Deinitialize was called without first calling
> initialize.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +DeinitVariablePolicyLib (
>
> + VOID
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + Status = EFI_SUCCESS;
>
> +
>
> + if (mGetVariableHelper == NULL) {
>
> + Status = EFI_NOT_READY;
>
> + }
>
> +
>
> + if (!EFI_ERROR( Status )) {
>
> + Status = VariablePolicyExtraDeinit();
>
> + }
>
> +
>
> + if (!EFI_ERROR( Status )) {
>
> + mGetVariableHelper = NULL;
>
> + mInterfaceLocked = FALSE;
>
> + mProtectionDisabled = FALSE;
>
> + mCurrentTableSize = 0;
>
> + mCurrentTableUsage = 0;
>
> + mCurrentTableCount = 0;
>
> +
>
> + if (mPolicyTable != NULL) {
>
> + FreePool( mPolicyTable );
>
> + mPolicyTable = NULL;
>
> + }
>
> + }
>
> +
>
> + return Status;
>
> +}
>
> diff --git
> a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/Variable
> PolicyUnitTest.c
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/Variable
> PolicyUnitTest.c
> new file mode 100644
> index 000000000000..f133f2f30e36
> --- /dev/null
> +++
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/Variable
> PolicyUnitTest.c
> @@ -0,0 +1,2436 @@
> +/** @file -- VariablePolicyUnitTest.c
>
> +UnitTest for...
>
> +Business logic for Variable Policy enforcement.
>
> +
>
> +Copyright (c) Microsoft Corporation.
>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#include <stdio.h>
>
> +#include <string.h>
>
> +#include <stdarg.h>
>
> +#include <stddef.h>
>
> +#include <setjmp.h>
>
> +#include <cmocka.h>
>
> +
>
> +#include <Uefi.h>
>
> +#include <Library/PrintLib.h>
>
> +#include <Library/DebugLib.h>
>
> +#include <Library/UnitTestLib.h>
>
> +#include <Library/BaseMemoryLib.h>
>
> +#include <Library/MemoryAllocationLib.h>
>
> +#include <Library/BaseLib.h>
>
> +
>
> +#include <Guid/VariableFormat.h>
>
> +
>
> +#include <Protocol/VariablePolicy.h>
>
> +#include <Library/VariablePolicyLib.h>
>
> +
>
> +// MU_CHANGE - Turn this off for now. Try to turn it back on with extra
> build options.
>
> +// #ifndef INTERNAL_UNIT_TEST
>
> +// #error Make sure to build thie with INTERNAL_UNIT_TEST enabled!
> Otherwise, some important tests may be skipped!
>
> +// #endif
>
> +
>
> +
>
> +#define UNIT_TEST_NAME "UEFI Variable Policy UnitTest"
>
> +#define UNIT_TEST_VERSION "0.5"
>
> +
>
> +///=== TEST DATA
> ==========================================================
> ========================
>
> +
>
> +#pragma pack(push, 1)
>
> +typedef struct _SIMPLE_VARIABLE_POLICY_ENTRY {
>
> + VARIABLE_POLICY_ENTRY Header;
>
> + CHAR16 Name[];
>
> +} SIMPLE_VARIABLE_POLICY_ENTRY;
>
> +#define EXPANDED_VARIABLE_POLICY_ENTRY_VAR_NAME_LENGTH 1001
> // 1000 characters + terminator.
>
> +#define EXPANDED_VARIABLE_POLICY_ENTRY_VAR_NAME_SIZE
> (EXPANDED_VARIABLE_POLICY_ENTRY_VAR_NAME_LENGTH *
> sizeof(CHAR16))
>
> +typedef struct _EXPANDED_VARIABLE_POLICY_ENTRY {
>
> + VARIABLE_POLICY_ENTRY Header;
>
> + VARIABLE_LOCK_ON_VAR_STATE_POLICY StatePolicy;
>
> + CHAR16
> StateName[EXPANDED_VARIABLE_POLICY_ENTRY_VAR_NAME_LENGTH];
>
> + CHAR16
> Name[EXPANDED_VARIABLE_POLICY_ENTRY_VAR_NAME_LENGTH];
>
> +} EXPANDED_VARIABLE_POLICY_ENTRY;
>
> +#pragma pack(pop)
>
> +
>
> +// {F955BA2D-4A2C-480C-BFD1-3CC522610592}
>
> +#define TEST_GUID_1 { 0xf955ba2d, 0x4a2c, 0x480c, { 0xbf, 0xd1, 0x3c, 0xc5,
> 0x22, 0x61, 0x5, 0x92 } }
>
> +EFI_GUID mTestGuid1 = TEST_GUID_1;
>
> +// {2DEA799E-5E73-43B9-870E-C945CE82AF3A}
>
> +#define TEST_GUID_2 { 0x2dea799e, 0x5e73, 0x43b9, { 0x87, 0xe, 0xc9, 0x45,
> 0xce, 0x82, 0xaf, 0x3a } }
>
> +EFI_GUID mTestGuid2 = TEST_GUID_2;
>
> +// {698A2BFD-A616-482D-B88C-7100BD6682A9}
>
> +#define TEST_GUID_3 { 0x698a2bfd, 0xa616, 0x482d, { 0xb8, 0x8c, 0x71, 0x0,
> 0xbd, 0x66, 0x82, 0xa9 } }
>
> +EFI_GUID mTestGuid3 = TEST_GUID_3;
>
> +
>
> +#define TEST_VAR_1_NAME L"TestVar1"
>
> +#define TEST_VAR_2_NAME L"TestVar2"
>
> +#define TEST_VAR_3_NAME L"TestVar3"
>
> +
>
> +#define TEST_POLICY_ATTRIBUTES_NULL 0
>
> +#define TEST_POLICY_MIN_SIZE_NULL 0
>
> +#define TEST_POLICY_MAX_SIZE_NULL MAX_UINT32
>
> +
>
> +#define TEST_POLICY_MIN_SIZE_10 10
>
> +#define TEST_POLICY_MAX_SIZE_200 200
>
> +
>
> +#define TEST_300_HASHES_STRING
> L"##################################################"\
>
> +
> "##################################################"\
>
> +
> "##################################################"\
>
> +
> "##################################################"\
>
> +
> "##################################################"\
>
> +
> "##################################################"
>
> +
>
> +
>
> +///=== HELPER FUNCTIONS
> ==========================================================
> =================
>
> +
>
> +/**
>
> + Helper function to initialize a VARIABLE_POLICY_ENTRY structure with a
> Name and StateName.
>
> +
>
> + Takes care of all the messy packing.
>
> +
>
> + @param[in,out] Entry
>
> + @param[in] Name [Optional]
>
> + @param[in] StateName [Optional]
>
> +
>
> + @retval TRUE
>
> + @retval FALSE
>
> +
>
> +**/
>
> +STATIC
>
> +BOOLEAN
>
> +InitExpVarPolicyStrings (
>
> + EXPANDED_VARIABLE_POLICY_ENTRY *Entry,
>
> + CHAR16 *Name, OPTIONAL
>
> + CHAR16 *StateName OPTIONAL
>
> + )
>
> +{
>
> + UINTN NameSize;
>
> + UINTN StateNameSize;
>
> +
>
> + NameSize = Name == NULL ? 0 : StrSize( Name );
>
> + StateNameSize = StateName == NULL ? 0 : StrSize( StateName );
>
> +
>
> + if (NameSize > EXPANDED_VARIABLE_POLICY_ENTRY_VAR_NAME_SIZE ||
> NameSize > MAX_UINT16 ||
>
> + StateNameSize >
> EXPANDED_VARIABLE_POLICY_ENTRY_VAR_NAME_SIZE || StateNameSize >
> MAX_UINT16) {
>
> + return FALSE;
>
> + }
>
> +
>
> + Entry->Header.OffsetToName = sizeof(VARIABLE_POLICY_ENTRY);
>
> + if (StateName != NULL) {
>
> + Entry->Header.OffsetToName +=
> (UINT16)sizeof(VARIABLE_LOCK_ON_VAR_STATE_POLICY) +
> (UINT16)StateNameSize;
>
> + }
>
> + Entry->Header.Size = Entry->Header.OffsetToName + (UINT16)NameSize;
>
> +
>
> + CopyMem( (UINT8*)Entry + Entry->Header.OffsetToName, Name,
> NameSize );
>
> + if (StateName != NULL) {
>
> + CopyMem( (UINT8*)Entry + sizeof(VARIABLE_POLICY_ENTRY) +
> sizeof(VARIABLE_LOCK_ON_VAR_STATE_POLICY), StateName,
> StateNameSize );
>
> + }
>
> +
>
> + return TRUE;
>
> +}
>
> +
>
> +/**
>
> + Mocked version of GetVariable, for testing.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +StubGetVariableNull (
>
> + IN CHAR16 *VariableName,
>
> + IN EFI_GUID *VendorGuid,
>
> + OUT UINT32 *Attributes, OPTIONAL
>
> + IN OUT UINTN *DataSize,
>
> + OUT VOID *Data OPTIONAL
>
> + )
>
> +{
>
> + UINT32 MockedAttr;
>
> + UINTN MockedDataSize;
>
> + VOID *MockedData;
>
> + EFI_STATUS MockedReturn;
>
> +
>
> + check_expected_ptr( VariableName );
>
> + check_expected_ptr( VendorGuid );
>
> + check_expected_ptr( DataSize );
>
> +
>
> + MockedAttr = (UINT32)mock();
>
> + MockedDataSize = (UINTN)mock();
>
> + MockedData = (VOID*)mock();
>
> + MockedReturn = (EFI_STATUS)mock();
>
> +
>
> + if (Attributes != NULL) {
>
> + *Attributes = MockedAttr;
>
> + }
>
> + if (Data != NULL && !EFI_ERROR(MockedReturn)) {
>
> + CopyMem( Data, MockedData, MockedDataSize );
>
> + }
>
> +
>
> + *DataSize = MockedDataSize;
>
> +
>
> + return MockedReturn;
>
> +}
>
> +
>
> +//
>
> +// Anything you think might be helpful that isn't a test itself.
>
> +//
>
> +
>
> +/**
>
> + This is a common setup function that will ensure the library is always
> initialized
>
> + with the stubbed GetVariable.
>
> +
>
> + Not used by all test cases, but by most.
>
> +**/
>
> +STATIC
>
> +UNIT_TEST_STATUS
>
> +LibInitMocked (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + return EFI_ERROR(InitVariablePolicyLib( StubGetVariableNull )) ?
> UNIT_TEST_ERROR_PREREQUISITE_NOT_MET : UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Common cleanup function to make sure that the library is always de-
> initialized prior
>
> + to the next test case.
>
> +*/
>
> +STATIC
>
> +VOID
>
> +LibCleanup (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + DeinitVariablePolicyLib();
>
> +}
>
> +
>
> +
>
> +///=== TEST CASES
> ==========================================================
> =======================
>
> +
>
> +///===== ARCHITECTURAL SUITE
> ==================================================
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +ShouldBeAbleToInitAndDeinitTheLibrary (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + Status = InitVariablePolicyLib( StubGetVariableNull );
>
> + UT_ASSERT_NOT_EFI_ERROR( Status );
>
> +
>
> + UT_ASSERT_TRUE( IsVariablePolicyLibInitialized() );
>
> +
>
> + Status = DeinitVariablePolicyLib();
>
> + UT_ASSERT_NOT_EFI_ERROR( Status );
>
> +
>
> + UT_ASSERT_FALSE( IsVariablePolicyLibInitialized() );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +ShouldNotBeAbleToInitializeTheLibraryTwice (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + Status = InitVariablePolicyLib( StubGetVariableNull );
>
> + UT_ASSERT_NOT_EFI_ERROR( Status );
>
> + Status = InitVariablePolicyLib( StubGetVariableNull );
>
> + UT_ASSERT_TRUE( EFI_ERROR( Status ) );
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +ShouldFailDeinitWithoutInit (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + Status = DeinitVariablePolicyLib();
>
> + UT_ASSERT_TRUE( EFI_ERROR( Status ) );
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +ApiCommandsShouldNotRespondIfLibIsUninitialized (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY TestPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> + UINT8 DummyData[8];
>
> + UINT32 DummyDataSize = sizeof(DummyData);
>
> +
>
> + // This test should not start with an initialized library.
>
> +
>
> + // Verify that all API commands fail.
>
> + UT_ASSERT_TRUE( EFI_ERROR( LockVariablePolicy() ) );
>
> + UT_ASSERT_TRUE( EFI_ERROR( DisableVariablePolicy() ) );
>
> +
> UT_ASSERT_TRUE( EFI_ERROR( RegisterVariablePolicy( &TestPolicy.Header )
> ) );
>
> + UT_ASSERT_TRUE( EFI_ERROR( DumpVariablePolicy( DummyData,
> &DummyDataSize ) ) );
>
> + UT_ASSERT_FALSE( IsVariablePolicyInterfaceLocked() );
>
> + UT_ASSERT_FALSE( IsVariablePolicyEnabled() );
>
> + UT_ASSERT_TRUE( EFI_ERROR( ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_NV_BS,
>
> + sizeof(DummyData),
>
> + DummyData ) ) );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +
>
> +///===== INTERNAL FUNCTION SUITE
> ==============================================
>
> +
>
> +#ifdef INTERNAL_UNIT_TEST
>
> +
>
> +BOOLEAN
>
> +EvaluatePolicyMatch (
>
> + IN CONST VARIABLE_POLICY_ENTRY *EvalEntry,
>
> + IN CONST CHAR16 *VariableName,
>
> + IN CONST EFI_GUID *VendorGuid,
>
> + OUT UINT8 *MatchPriority OPTIONAL
>
> + );
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +PoliciesShouldMatchByNameAndGuid (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY MatchCheckPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> + CHAR16 *CheckVar1Name = TEST_VAR_1_NAME;
>
> + CHAR16 *CheckVar2Name = TEST_VAR_2_NAME;
>
> +
>
> + // Make sure that a different name does not match.
>
> + UT_ASSERT_FALSE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckVar2Name, &mTestGuid1, NULL ) );
>
> +
>
> + // Make sure that a different GUID does not match.
>
> + UT_ASSERT_FALSE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckVar1Name, &mTestGuid2, NULL ) );
>
> +
>
> + // Make sure that the same name and GUID match.
>
> + UT_ASSERT_TRUE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckVar1Name, &mTestGuid1, NULL ) );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +WildcardPoliciesShouldMatchDigits (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY MatchCheckPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(L"Wildcard#VarName##"),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + L"Wildcard#VarName##"
>
> + };
>
> + CHAR16 *CheckVar1Name = L"Wildcard1VarName12";
>
> + CHAR16 *CheckVar2Name = L"Wildcard2VarName34";
>
> + CHAR16 *CheckVarBName = L"WildcardBVarName56";
>
> + CHAR16 *CheckVarHName = L"Wildcard#VarName56";
>
> +
>
> + // Make sure that two different sets of wildcard numbers match.
>
> + UT_ASSERT_TRUE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckVar1Name, &mTestGuid1, NULL ) );
>
> + UT_ASSERT_TRUE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckVar2Name, &mTestGuid1, NULL ) );
>
> +
>
> + // Make sure that the non-number charaters don't match.
>
> + UT_ASSERT_FALSE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckVarBName, &mTestGuid1, NULL ) );
>
> +
>
> + // Make sure that '#' signs don't match.
>
> + UT_ASSERT_FALSE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckVarHName, &mTestGuid1, NULL ) );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +WildcardPoliciesShouldMatchDigitsAdvanced (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY MatchCheckPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_300_HASHES_STRING),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_300_HASHES_STRING
>
> + };
>
> + CHAR16 *CheckShorterString =
> L"01234567890123456789012345678901234567890123456789";
>
> + CHAR16 *CheckValidString =
> L"01234567890123456789012345678901234567890123456789"\
>
> +
> "01234567890123456789012345678901234567890123456789"\
>
> +
> "01234567890123456789012345678901234567890123456789"\
>
> +
> "01234567890123456789012345678901234567890123456789"\
>
> +
> "01234567890123456789012345678901234567890123456789"\
>
> +
> "01234567890123456789012345678901234567890123456789";
>
> + CHAR16 *CheckLongerString =
> L"01234567890123456789012345678901234567890123456789"\
>
> +
> "01234567890123456789012345678901234567890123456789"\
>
> +
> "01234567890123456789012345678901234567890123456789"\
>
> +
> "01234567890123456789012345678901234567890123456789"\
>
> +
> "01234567890123456789012345678901234567890123456789"\
>
> +
> "01234567890123456789012345678901234567890123456789"\
>
> +
> "01234567890123456789012345678901234567890123456789";
>
> + UINT8 MatchPriority;
>
> +
>
> + // Make sure that the shorter and the longer do not match.
>
> + UT_ASSERT_FALSE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckShorterString, &mTestGuid1, NULL ) );
>
> + UT_ASSERT_FALSE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckLongerString, &mTestGuid1, NULL ) );
>
> +
>
> + // Make sure that the valid one matches and has the expected priority.
>
> + UT_ASSERT_TRUE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckValidString, &mTestGuid1, &MatchPriority ) );
>
> + UT_ASSERT_EQUAL( MatchPriority, MAX_UINT8 );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +WildcardPoliciesShouldMatchNamespaces (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + VARIABLE_POLICY_ENTRY MatchCheckPolicy = {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + };
>
> + CHAR16 *CheckVar1Name = L"Wildcard1VarName12";
>
> + CHAR16 *CheckVar2Name = L"Wildcard2VarName34";
>
> + CHAR16 *CheckVarBName = L"WildcardBVarName56";
>
> + CHAR16 *CheckVarHName = L"Wildcard#VarName56";
>
> +
>
> + // Make sure that all names in the same namespace match.
>
> + UT_ASSERT_TRUE( EvaluatePolicyMatch( &MatchCheckPolicy,
> CheckVar1Name, &mTestGuid1, NULL ) );
>
> + UT_ASSERT_TRUE( EvaluatePolicyMatch( &MatchCheckPolicy,
> CheckVar2Name, &mTestGuid1, NULL ) );
>
> + UT_ASSERT_TRUE( EvaluatePolicyMatch( &MatchCheckPolicy,
> CheckVarBName, &mTestGuid1, NULL ) );
>
> + UT_ASSERT_TRUE( EvaluatePolicyMatch( &MatchCheckPolicy,
> CheckVarHName, &mTestGuid1, NULL ) );
>
> +
>
> + // Make sure that different namespace doesn't match.
>
> + UT_ASSERT_FALSE( EvaluatePolicyMatch( &MatchCheckPolicy,
> CheckVar1Name, &mTestGuid2, NULL ) );
>
> +
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +MatchPrioritiesShouldFollowRules (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY MatchCheckPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(L"Wildcard1VarName12"),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + L"Wildcard1VarName12"
>
> + };
>
> + CHAR16 CheckVar1Name[] = L"Wildcard1VarName12";
>
> + CHAR16 MatchVar1Name[] = L"Wildcard1VarName12";
>
> + CHAR16 MatchVar2Name[] = L"Wildcard#VarName12";
>
> + CHAR16 MatchVar3Name[] = L"Wildcard#VarName#2";
>
> + CHAR16 MatchVar4Name[] = L"Wildcard#VarName##";
>
> + UINT8 MatchPriority;
>
> +
>
> + // Check with a perfect match.
>
> + CopyMem( &MatchCheckPolicy.Name, MatchVar1Name,
> sizeof(MatchVar1Name) );
>
> + UT_ASSERT_TRUE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckVar1Name, &mTestGuid1, &MatchPriority ) );
>
> + UT_ASSERT_EQUAL( MatchPriority, 0 );
>
> +
>
> + // Check with progressively lower priority matches.
>
> + CopyMem( &MatchCheckPolicy.Name, MatchVar2Name,
> sizeof(MatchVar2Name) );
>
> + UT_ASSERT_TRUE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckVar1Name, &mTestGuid1, &MatchPriority ) );
>
> + UT_ASSERT_EQUAL( MatchPriority, 1 );
>
> + CopyMem( &MatchCheckPolicy.Name, MatchVar3Name,
> sizeof(MatchVar3Name) );
>
> + UT_ASSERT_TRUE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckVar1Name, &mTestGuid1, &MatchPriority ) );
>
> + UT_ASSERT_EQUAL( MatchPriority, 2 );
>
> + CopyMem( &MatchCheckPolicy.Name, MatchVar4Name,
> sizeof(MatchVar4Name) );
>
> + UT_ASSERT_TRUE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckVar1Name, &mTestGuid1, &MatchPriority ) );
>
> + UT_ASSERT_EQUAL( MatchPriority, 3 );
>
> +
>
> + // Check against the entire namespace.
>
> + MatchCheckPolicy.Header.Size = sizeof(VARIABLE_POLICY_ENTRY);
>
> + UT_ASSERT_TRUE( EvaluatePolicyMatch( &MatchCheckPolicy.Header,
> CheckVar1Name, &mTestGuid1, &MatchPriority ) );
>
> + UT_ASSERT_EQUAL( MatchPriority, MAX_UINT8 );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +#endif // INTERNAL_UNIT_TEST
>
> +
>
> +
>
> +///=== POLICY MANIPULATION SUITE
> ==============================================
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldAllowNamespaceWildcards (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + L""
>
> + };
>
> +
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldAllowStateVarsForNamespaces (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + EXPANDED_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + 0, // Will be populated by init helper.
>
> + 0, // Will be populated by init helper.
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
>
> + },
>
> + {
>
> + TEST_GUID_2,
>
> + 1, // Value
>
> + 0 // Padding
>
> + },
>
> + L"",
>
> + L""
>
> + };
>
> + UT_ASSERT_TRUE( InitExpVarPolicyStrings( &ValidationPolicy, NULL,
> TEST_VAR_2_NAME ) );
>
> +
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldRejectNullPointers (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( NULL ),
> EFI_INVALID_PARAMETER );
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldRejectBadRevisions (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> +
>
> + ValidationPolicy.Header.Version = MAX_UINT32;
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldRejectBadSizes (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> +
>
> + ValidationPolicy.Header.Size = sizeof(VARIABLE_POLICY_ENTRY) - 2;
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldRejectBadOffsets (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + EXPANDED_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + 0, // Will be populated by init helper.
>
> + 0, // Will be populated by init helper.
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
>
> + },
>
> + {
>
> + TEST_GUID_2,
>
> + 1, // Value
>
> + 0 // Padding
>
> + },
>
> + L"",
>
> + L""
>
> + };
>
> + UT_ASSERT_TRUE( InitExpVarPolicyStrings( &ValidationPolicy,
> TEST_VAR_1_NAME, TEST_VAR_2_NAME ) );
>
> +
>
> + // Check for an offset outside the size bounds.
>
> + ValidationPolicy.Header.OffsetToName = ValidationPolicy.Header.Size + 1;
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + // Check for an offset inside the policy header.
>
> + ValidationPolicy.Header.OffsetToName = sizeof(VARIABLE_POLICY_ENTRY)
> - 2;
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + // Check for an offset inside the state policy header.
>
> + ValidationPolicy.Header.OffsetToName = sizeof(VARIABLE_POLICY_ENTRY)
> + 2;
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + // Check for a ridiculous offset.
>
> + ValidationPolicy.Header.OffsetToName = MAX_UINT16;
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldRejectMissingStateStrings (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + EXPANDED_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + 0, // Will be populated by init helper.
>
> + 0, // Will be populated by init helper.
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
>
> + },
>
> + {
>
> + TEST_GUID_2,
>
> + 1, // Value
>
> + 0 // Padding
>
> + },
>
> + L"",
>
> + L""
>
> + };
>
> + UT_ASSERT_TRUE( InitExpVarPolicyStrings( &ValidationPolicy,
> TEST_VAR_1_NAME, TEST_VAR_2_NAME ) );
>
> +
>
> + // Remove the state string and copy the Name into it's place.
>
> + // Also adjust the offset.
>
> + ValidationPolicy.Header.Size = sizeof(VARIABLE_POLICY_ENTRY) +
> sizeof(VARIABLE_LOCK_ON_VAR_STATE_POLICY) +
> sizeof(TEST_VAR_1_NAME);
>
> + ValidationPolicy.Header.OffsetToName = sizeof(VARIABLE_POLICY_ENTRY)
> + sizeof(VARIABLE_LOCK_ON_VAR_STATE_POLICY);
>
> + CopyMem( (UINT8*)&ValidationPolicy +
> ValidationPolicy.Header.OffsetToName, TEST_VAR_1_NAME,
> sizeof(TEST_VAR_1_NAME) );
>
> +
>
> + // Make sure that this structure fails.
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldRejectStringsMissingNull (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + EXPANDED_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + 0, // Will be populated by init helper.
>
> + 0, // Will be populated by init helper.
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
>
> + },
>
> + {
>
> + TEST_GUID_2,
>
> + 1, // Value
>
> + 0 // Padding
>
> + },
>
> + L"",
>
> + L""
>
> + };
>
> + UT_ASSERT_TRUE( InitExpVarPolicyStrings( &ValidationPolicy,
> TEST_VAR_1_NAME, TEST_VAR_2_NAME ) );
>
> +
>
> + // Removing the NULL from the Name should fail.
>
> + ValidationPolicy.Header.Size = ValidationPolicy.Header.Size -
> sizeof(CHAR16);
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + // Removing the NULL from the State Name is a little trickier.
>
> + // Copy the Name up one byte.
>
> + ValidationPolicy.Header.OffsetToName =
> ValidationPolicy.Header.OffsetToName - sizeof(CHAR16);
>
> + CopyMem( (UINT8*)&ValidationPolicy +
> ValidationPolicy.Header.OffsetToName, TEST_VAR_1_NAME,
> sizeof(TEST_VAR_1_NAME) );
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldRejectMalformedStrings (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + EXPANDED_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + 0, // Will be populated by init helper.
>
> + 0, // Will be populated by init helper.
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
>
> + },
>
> + {
>
> + TEST_GUID_2,
>
> + 1, // Value
>
> + 0 // Padding
>
> + },
>
> + L"",
>
> + L""
>
> + };
>
> + UT_ASSERT_TRUE( InitExpVarPolicyStrings( &ValidationPolicy,
> TEST_VAR_1_NAME, TEST_VAR_2_NAME ) );
>
> +
>
> + // Bisecting the NULL from the Name should fail.
>
> + ValidationPolicy.Header.Size = ValidationPolicy.Header.Size - 1;
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + // Bisecting the NULL from the State Name is a little trickier.
>
> + // Copy the Name up one byte.
>
> + ValidationPolicy.Header.OffsetToName =
> ValidationPolicy.Header.OffsetToName - 1;
>
> + CopyMem( (UINT8*)&ValidationPolicy +
> ValidationPolicy.Header.OffsetToName, TEST_VAR_1_NAME,
> sizeof(TEST_VAR_1_NAME) );
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldRejectUnpackedPolicies (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + EXPANDED_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + 0, // Will be populated by init helper.
>
> + 0, // Will be populated by init helper.
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
>
> + },
>
> + {
>
> + TEST_GUID_2,
>
> + 1, // Value
>
> + 0 // Padding
>
> + },
>
> + L"",
>
> + L""
>
> + };
>
> + UT_ASSERT_TRUE( InitExpVarPolicyStrings( &ValidationPolicy,
> TEST_VAR_1_NAME, TEST_VAR_2_NAME ) );
>
> +
>
> + // Increase the size and move the Name out a bit.
>
> + ValidationPolicy.Header.Size = ValidationPolicy.Header.Size +
> sizeof(CHAR16);
>
> + ValidationPolicy.Header.OffsetToName =
> ValidationPolicy.Header.OffsetToName + sizeof(CHAR16);
>
> + CopyMem( (UINT8*)&ValidationPolicy +
> ValidationPolicy.Header.OffsetToName, TEST_VAR_1_NAME,
> sizeof(TEST_VAR_1_NAME) );
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + // Reintialize without the state policy and try the same test.
>
> + ValidationPolicy.Header.LockPolicyType =
> VARIABLE_POLICY_TYPE_NO_LOCK;
>
> + UT_ASSERT_TRUE( InitExpVarPolicyStrings( &ValidationPolicy,
> TEST_VAR_1_NAME, NULL ) );
>
> + ValidationPolicy.Header.Size = ValidationPolicy.Header.Size +
> sizeof(CHAR16);
>
> + ValidationPolicy.Header.OffsetToName =
> ValidationPolicy.Header.OffsetToName + sizeof(CHAR16);
>
> + CopyMem( (UINT8*)&ValidationPolicy +
> ValidationPolicy.Header.OffsetToName, TEST_VAR_1_NAME,
> sizeof(TEST_VAR_1_NAME) );
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldRejectInvalidNameCharacters (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + // EXPANDED_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + // {
>
> + // VARIABLE_POLICY_ENTRY_REVISION,
>
> + // 0, // Will be populated by init helper.
>
> + // 0, // Will be populated by init helper.
>
> + // TEST_GUID_1,
>
> + // TEST_POLICY_MIN_SIZE_NULL,
>
> + // TEST_POLICY_MAX_SIZE_NULL,
>
> + // TEST_POLICY_ATTRIBUTES_NULL,
>
> + // TEST_POLICY_ATTRIBUTES_NULL,
>
> + // VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
>
> + // },
>
> + // {
>
> + // TEST_GUID_2,
>
> + // 1, // Value
>
> + // 0 // Padding
>
> + // },
>
> + // L"",
>
> + // L""
>
> + // };
>
> +
>
> + // Currently, there are no known invalid characters.
>
> + // '#' in LockPolicy->Name are taken as literal.
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldRejectBadPolicyConstraints (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> +
>
> + // Make sure that invalid MAXes are rejected.
>
> + ValidationPolicy.Header.MaxSize = 0;
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldRejectUnknownLockPolicies (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> +
>
> + ValidationPolicy.Header.LockPolicyType =
> VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE + 1;
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> + ValidationPolicy.Header.LockPolicyType =
> VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE + 1;
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldRejectPolicesWithTooManyWildcards (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_300_HASHES_STRING),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_300_HASHES_STRING
>
> + };
>
> +
>
> + // 300 Hashes is currently larger than the possible maximum match priority.
>
> + UT_ASSERT_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Header ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +RegisterShouldRejectDuplicatePolicies (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> +
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> +
> UT_ASSERT_STATUS_EQUAL( RegisterVariablePolicy( &ValidationPolicy.Head
> er ), EFI_ALREADY_STARTED );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +MinAndMaxSizePoliciesShouldBeHonored (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_10,
>
> + TEST_POLICY_MAX_SIZE_200,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> + EFI_STATUS PolicyCheck;
>
> + UINT8 DummyData[TEST_POLICY_MAX_SIZE_200+1];
>
> +
>
> +
>
> + // Without a policy, there should be no constraints on variable creation.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_NV_BS,
>
> + TEST_POLICY_MAX_SIZE_200+1,
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // Set a policy to test against.
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> +
>
> + // With a policy, make sure that sizes outsize the target range fail.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_NV_BS,
>
> + TEST_POLICY_MAX_SIZE_200+1,
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> +
>
> + // With a policy, make sure that sizes outsize the target range fail.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_NV_BS,
>
> + TEST_POLICY_MIN_SIZE_10-1,
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> +
>
> + // With a policy, make sure a valid variable is still valid.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_NV_BS,
>
> + TEST_POLICY_MIN_SIZE_10+1,
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +AttributeMustPoliciesShouldBeHonored (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + VARIABLE_ATTRIBUTE_NV_BS_RT,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> + EFI_STATUS PolicyCheck;
>
> + UINT8 DummyData[12];
>
> +
>
> +
>
> + // Without a policy, there should be no constraints on variable creation.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // Set a policy to test against.
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> +
>
> + // With a policy, make sure that no attributes fail.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> +
>
> + // With a policy, make sure that some -- but not all -- attributes fail.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> +
>
> + // With a policy, make sure that all attributes pass.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_NV_BS_RT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // With a policy, make sure that all attributes -- plus some -- pass.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +AttributeCantPoliciesShouldBeHonored (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> + EFI_STATUS PolicyCheck;
>
> + UINT8 DummyData[12];
>
> +
>
> +
>
> + // Without a policy, there should be no constraints on variable creation.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // Set a policy to test against.
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> +
>
> + // With a policy, make sure that forbidden attributes fail.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> +
> EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> +
>
> + // With a policy, make sure that a mixture of attributes -- including the
> forbidden -- fail.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> +
>
> + // With a policy, make sure that attributes without the forbidden pass.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_NV_BS_RT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +VariablesShouldBeDeletableRegardlessOfSize (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_10,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> + EFI_STATUS PolicyCheck;
>
> + UINT8 DummyData[TEST_POLICY_MAX_SIZE_200+1];
>
> +
>
> + // Create a policy enforcing a minimum variable size.
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> +
>
> + // Make sure that a normal set would fail.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_NV_BS,
>
> + TEST_POLICY_MIN_SIZE_10-1,
>
> + DummyData );
>
> + UT_ASSERT_STATUS_EQUAL( PolicyCheck, EFI_INVALID_PARAMETER );
>
> +
>
> + // Now make sure that a delete would succeed.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_NV_BS,
>
> + 0,
>
> + NULL );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +LockNowPoliciesShouldBeHonored (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_LOCK_NOW
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> + EFI_STATUS PolicyCheck;
>
> + UINT8 DummyData[12];
>
> +
>
> +
>
> + // Without a policy, there should be no constraints on variable creation.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // Set a policy to test against.
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> +
>
> + // With a policy, make sure that writes immediately fail.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +LockOnCreatePoliciesShouldBeHonored (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_LOCK_ON_CREATE
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> + EFI_STATUS PolicyCheck;
>
> + UINT8 DummyData[12];
>
> + UINTN ExpectedDataSize;
>
> +
>
> +
>
> + // Without a policy, there should be no constraints on variable creation.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // Set a policy to test against.
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> +
>
> + // Set consistent expectations on what the calls are looking for.
>
> + expect_memory_count( StubGetVariableNull, VariableName,
> TEST_VAR_1_NAME, sizeof(TEST_VAR_1_NAME), 2 );
>
> + expect_memory_count( StubGetVariableNull, VendorGuid, &mTestGuid1,
> sizeof(mTestGuid1), 2 );
>
> + ExpectedDataSize = 0;
>
> + expect_memory_count( StubGetVariableNull, DataSize,
> &ExpectedDataSize, sizeof(ExpectedDataSize), 2 );
>
> +
>
> + // With a policy, make sure that writes still work, since the variable doesn't
> exist.
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, 0 ); // Size
>
> + will_return( StubGetVariableNull, NULL ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_NOT_FOUND ); // Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // With a policy, make sure that a call with an "existing" variable fails.
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, 10 ); // Size
>
> + will_return( StubGetVariableNull, NULL ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_BUFFER_TOO_SMALL ); //
> Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +LockOnStatePoliciesShouldBeHonored (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + EXPANDED_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + 0, // Will be populated by init helper.
>
> + 0, // Will be populated by init helper.
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
>
> + },
>
> + {
>
> + TEST_GUID_2,
>
> + 20, // Value
>
> + 0 // Padding
>
> + },
>
> + L"",
>
> + L""
>
> + };
>
> + EFI_STATUS PolicyCheck;
>
> + UINT8 DummyData[12];
>
> + UINT8 ValidationStateVar;
>
> + UINTN ExpectedDataSize;
>
> + UT_ASSERT_TRUE( InitExpVarPolicyStrings( &ValidationPolicy,
> TEST_VAR_1_NAME, TEST_VAR_2_NAME ) );
>
> +
>
> +
>
> + // Without a policy, there should be no constraints on variable creation.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // Set a policy to test against.
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> +
>
> + // Set consistent expectations on what the calls are looking for.
>
> + expect_memory_count( StubGetVariableNull, VariableName,
> TEST_VAR_2_NAME, sizeof(TEST_VAR_2_NAME), 5 );
>
> + expect_memory_count( StubGetVariableNull, VendorGuid, &mTestGuid2,
> sizeof(mTestGuid2), 5 );
>
> + ExpectedDataSize = 1;
>
> + expect_memory_count( StubGetVariableNull, DataSize,
> &ExpectedDataSize, sizeof(ExpectedDataSize), 5 );
>
> +
>
> + // With a policy, make sure that writes still work, since the variable doesn't
> exist.
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, 0 ); // Size
>
> + will_return( StubGetVariableNull, NULL ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_NOT_FOUND ); // Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // With a policy, make sure that a state variable that's too large doesn't lock
> the variable.
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, 10 ); // Size
>
> + will_return( StubGetVariableNull, NULL ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_BUFFER_TOO_SMALL ); //
> Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // With a policy, check a state variable with the wrong value.
>
> + ValidationStateVar = 0;
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, sizeof(ValidationStateVar) ); // Size
>
> + will_return( StubGetVariableNull, &ValidationStateVar ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_SUCCESS ); // Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // With a policy, check a state variable with another wrong value.
>
> + ValidationStateVar = 10;
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, sizeof(ValidationStateVar) ); // Size
>
> + will_return( StubGetVariableNull, &ValidationStateVar ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_SUCCESS ); // Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // With a policy, make sure that a call with a correct state variable fails.
>
> + ValidationStateVar = 20;
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, sizeof(ValidationStateVar) ); // Size
>
> + will_return( StubGetVariableNull, &ValidationStateVar ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_SUCCESS ); // Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +LockOnStatePoliciesShouldApplyToNamespaces (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + EXPANDED_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + 0, // Will be populated by init helper.
>
> + 0, // Will be populated by init helper.
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
>
> + },
>
> + {
>
> + TEST_GUID_2,
>
> + 20, // Value
>
> + 0 // Padding
>
> + },
>
> + L"",
>
> + L""
>
> + };
>
> + EFI_STATUS PolicyCheck;
>
> + UINT8 DummyData[12];
>
> + UINT8 ValidationStateVar;
>
> + UINTN ExpectedDataSize;
>
> + UT_ASSERT_TRUE( InitExpVarPolicyStrings( &ValidationPolicy, NULL,
> TEST_VAR_2_NAME ) );
>
> +
>
> +
>
> + // Without a policy, there should be no constraints on variable creation.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_3_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // Set a policy to test against.
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> +
>
> + // Set consistent expectations on what the calls are looking for.
>
> + expect_memory_count( StubGetVariableNull, VariableName,
> TEST_VAR_2_NAME, sizeof(TEST_VAR_2_NAME), 4 );
>
> + expect_memory_count( StubGetVariableNull, VendorGuid, &mTestGuid2,
> sizeof(mTestGuid2), 4 );
>
> + ExpectedDataSize = 1;
>
> + expect_memory_count( StubGetVariableNull, DataSize,
> &ExpectedDataSize, sizeof(ExpectedDataSize), 4 );
>
> +
>
> + // With a policy, make sure that writes still work, since the variable doesn't
> exist.
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, 0 ); // Size
>
> + will_return( StubGetVariableNull, NULL ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_NOT_FOUND ); // Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, 0 ); // Size
>
> + will_return( StubGetVariableNull, NULL ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_NOT_FOUND ); // Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_3_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // With a policy, make sure that a call with a correct state variable fails.
>
> + ValidationStateVar = 20;
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, sizeof(ValidationStateVar) ); // Size
>
> + will_return( StubGetVariableNull, &ValidationStateVar ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_SUCCESS ); // Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, sizeof(ValidationStateVar) ); // Size
>
> + will_return( StubGetVariableNull, &ValidationStateVar ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_SUCCESS ); // Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_3_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +LockOnStateShouldHandleErrorsGracefully (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + EXPANDED_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + 0, // Will be populated by init helper.
>
> + 0, // Will be populated by init helper.
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE
>
> + },
>
> + {
>
> + TEST_GUID_2,
>
> + 20, // Value
>
> + 0 // Padding
>
> + },
>
> + L"",
>
> + L""
>
> + };
>
> + EFI_STATUS PolicyCheck;
>
> + UINT8 DummyData[12];
>
> + UT_ASSERT_TRUE( InitExpVarPolicyStrings( &ValidationPolicy,
> TEST_VAR_1_NAME, TEST_VAR_2_NAME ) );
>
> +
>
> +
>
> + // Without a policy, there should be no constraints on variable creation.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // Set a policy to test against.
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> +
>
> + // Configure the stub to not care about parameters. We're testing errors.
>
> + expect_any_always( StubGetVariableNull, VariableName );
>
> + expect_any_always( StubGetVariableNull, VendorGuid );
>
> + expect_any_always( StubGetVariableNull, DataSize );
>
> +
>
> + // With a policy, make sure that writes still work, since the variable doesn't
> exist.
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, 0 ); // Size
>
> + will_return( StubGetVariableNull, NULL ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_NOT_FOUND ); // Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // Verify that state variables that are the wrong size won't lock the variable.
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, 0 ); // Size
>
> + will_return( StubGetVariableNull, NULL ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_BUFFER_TOO_SMALL ); //
> Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // Verify that unexpected errors default to locked.
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, 0 ); // Size
>
> + will_return( StubGetVariableNull, NULL ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_UNSUPPORTED ); // Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> +
>
> + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); //
> Attributes
>
> + will_return( StubGetVariableNull, 0 ); // Size
>
> + will_return( StubGetVariableNull, NULL ); // DataPtr
>
> + will_return( StubGetVariableNull, EFI_NOT_READY ); // Status
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +BestMatchPriorityShouldBeObeyed (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY ValidationPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(L"Wild12Card34Placeholder"),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + L"Wild12Card34Placeholder"
>
> + };
>
> + EFI_STATUS PolicyCheck;
>
> + UINT8 DummyData[70];
>
> + CHAR16 *PolicyName = (CHAR16*)((UINT8*)&ValidationPolicy +
> sizeof(VARIABLE_POLICY_ENTRY));
>
> + UINTN PolicyNameSize = sizeof(L"Wild12Card34Placeholder");
>
> + CHAR16 *FourWildcards = L"Wild##Card##Placeholder";
>
> + CHAR16 *ThreeWildcards = L"Wild##Card#4Placeholder";
>
> + CHAR16 *TwoWildcards = L"Wild##Card34Placeholder";
>
> + CHAR16 *OneWildcard = L"Wild#2Card34Placeholder";
>
> + CHAR16 *NoWildcards = L"Wild12Card34Placeholder";
>
> +
>
> + // Create all of the policies from least restrictive to most restrictive.
>
> + // NoWildcards should be the most restrictive.
>
> + ValidationPolicy.Header.MaxSize = 60;
>
> + ValidationPolicy.Header.Size = ValidationPolicy.Header.OffsetToName;
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> + ValidationPolicy.Header.Size += (UINT16)PolicyNameSize;
>
> + ValidationPolicy.Header.MaxSize = 50;
>
> + CopyMem( PolicyName, FourWildcards, PolicyNameSize );
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> + ValidationPolicy.Header.MaxSize = 40;
>
> + CopyMem( PolicyName, ThreeWildcards, PolicyNameSize );
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> + ValidationPolicy.Header.MaxSize = 30;
>
> + CopyMem( PolicyName, TwoWildcards, PolicyNameSize );
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> + ValidationPolicy.Header.MaxSize = 20;
>
> + CopyMem( PolicyName, OneWildcard, PolicyNameSize );
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> + ValidationPolicy.Header.MaxSize = 10;
>
> + CopyMem( PolicyName, NoWildcards, PolicyNameSize );
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &ValidationPolicy.Hea
> der ) );
>
> +
>
> + // Verify that variables only matching the namespace have the most
> flexible policy.
>
> + PolicyCheck = ValidateSetVariable( L"ArbitraryName",
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + 65,
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> + PolicyCheck = ValidateSetVariable( L"ArbitraryName",
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + 55,
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + // Verify that variables matching increasing characters get increasing policy
> restrictions.
>
> + PolicyCheck = ValidateSetVariable( L"Wild77Card77Placeholder",
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + 55,
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> + PolicyCheck = ValidateSetVariable( L"Wild77Card77Placeholder",
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + 45,
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + PolicyCheck = ValidateSetVariable( L"Wild77Card74Placeholder",
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + 45,
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> + PolicyCheck = ValidateSetVariable( L"Wild77Card74Placeholder",
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + 35,
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + PolicyCheck = ValidateSetVariable( L"Wild77Card34Placeholder",
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + 35,
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> + PolicyCheck = ValidateSetVariable( L"Wild77Card34Placeholder",
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + 25,
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + PolicyCheck = ValidateSetVariable( L"Wild72Card34Placeholder",
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + 25,
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> + PolicyCheck = ValidateSetVariable( L"Wild72Card34Placeholder",
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + 15,
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + PolicyCheck = ValidateSetVariable( L"Wild12Card34Placeholder",
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + 15,
>
> + DummyData );
>
> + UT_ASSERT_TRUE( EFI_ERROR( PolicyCheck ) );
>
> + PolicyCheck = ValidateSetVariable( L"Wild12Card34Placeholder",
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_BS_RT_AT,
>
> + 5,
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +
>
> +///=== POLICY UTILITY SUITE
> ===================================================
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +ShouldBeAbleToLockInterface (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY TestPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_NULL,
>
> + TEST_POLICY_MAX_SIZE_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> +
>
> + // Make sure it's not already locked.
>
> + UT_ASSERT_FALSE( IsVariablePolicyInterfaceLocked() );
>
> + // Lock it.
>
> + UT_ASSERT_NOT_EFI_ERROR( LockVariablePolicy() );
>
> + // Verify that it's locked.
>
> + UT_ASSERT_TRUE( IsVariablePolicyInterfaceLocked() );
>
> +
>
> + // Verify that all state-changing commands fail.
>
> + UT_ASSERT_TRUE( EFI_ERROR( LockVariablePolicy() ) );
>
> + UT_ASSERT_TRUE( EFI_ERROR( DisableVariablePolicy() ) );
>
> +
> UT_ASSERT_TRUE( EFI_ERROR( RegisterVariablePolicy( &TestPolicy.Header )
> ) );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +ShouldBeAbleToDisablePolicyEnforcement (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY TestPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_10,
>
> + TEST_POLICY_MAX_SIZE_200,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> + EFI_STATUS PolicyCheck;
>
> + UINT8 DummyData[TEST_POLICY_MIN_SIZE_10-1];
>
> +
>
> + // Make sure that the policy enforcement is currently enabled.
>
> + UT_ASSERT_TRUE( IsVariablePolicyEnabled() );
>
> + // Add a policy before it's disabled.
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &TestPolicy.Header ) );
>
> + // Disable the policy enforcement.
>
> + UT_ASSERT_NOT_EFI_ERROR( DisableVariablePolicy() );
>
> + // Make sure that the policy enforcement is currently disabled.
>
> + UT_ASSERT_FALSE( IsVariablePolicyEnabled() );
>
> +
>
> + // Check to make sure that a policy violation still passes.
>
> + PolicyCheck = ValidateSetVariable( TEST_VAR_1_NAME,
>
> + &mTestGuid1,
>
> + VARIABLE_ATTRIBUTE_NV_BS,
>
> + sizeof(DummyData),
>
> + DummyData );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +ShouldNotBeAbleToDisablePoliciesTwice (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + // Make sure that the policy enforcement is currently enabled.
>
> + UT_ASSERT_TRUE( IsVariablePolicyEnabled() );
>
> + // Disable the policy enforcement.
>
> + UT_ASSERT_NOT_EFI_ERROR( DisableVariablePolicy() );
>
> + // Make sure that the policy enforcement is currently disabled.
>
> + UT_ASSERT_FALSE( IsVariablePolicyEnabled() );
>
> + // Try to disable again and verify failure.
>
> + UT_ASSERT_TRUE( EFI_ERROR( DisableVariablePolicy() ) );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +ShouldBeAbleToAddNewPoliciesAfterDisabled (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY TestPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_10,
>
> + TEST_POLICY_MAX_SIZE_200,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> + EFI_STATUS PolicyCheck;
>
> +
>
> + // Make sure that the policy enforcement is currently enabled.
>
> + UT_ASSERT_TRUE( IsVariablePolicyEnabled() );
>
> + // Disable the policy enforcement.
>
> + UT_ASSERT_NOT_EFI_ERROR( DisableVariablePolicy() );
>
> +
>
> + // Make sure that new policy creation still works, it just won't be enforced.
>
> + PolicyCheck = RegisterVariablePolicy( &TestPolicy.Header );
>
> + UT_ASSERT_NOT_EFI_ERROR( PolicyCheck );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +ShouldBeAbleToLockAfterDisabled (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + // Make sure that the policy enforcement is currently enabled.
>
> + UT_ASSERT_TRUE( IsVariablePolicyEnabled() );
>
> + // Disable the policy enforcement.
>
> + UT_ASSERT_NOT_EFI_ERROR( DisableVariablePolicy() );
>
> +
>
> + // Make sure that we can lock in this state.
>
> + UT_ASSERT_FALSE( IsVariablePolicyInterfaceLocked() );
>
> + UT_ASSERT_NOT_EFI_ERROR( LockVariablePolicy() );
>
> + UT_ASSERT_TRUE( IsVariablePolicyInterfaceLocked() );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +ShouldBeAbleToDumpThePolicyTable (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY TestPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_10,
>
> + TEST_POLICY_MAX_SIZE_200,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> + EFI_STATUS PolicyCheck;
>
> + UINT32 DumpSize;
>
> + UINT32 BufferSize;
>
> + VOID *DumpBuffer;
>
> +
>
> + // For good measure, test some parameter validation.
>
> + UT_ASSERT_STATUS_EQUAL( DumpVariablePolicy( NULL, NULL ),
> EFI_INVALID_PARAMETER );
>
> + DumpSize = 10;
>
> + UT_ASSERT_STATUS_EQUAL( DumpVariablePolicy( NULL, &DumpSize ),
> EFI_INVALID_PARAMETER );
>
> +
>
> + // Now for the actual test case.
>
> +
>
> + // Allocate a buffer to hold the output.
>
> + BufferSize = sizeof(VARIABLE_POLICY_ENTRY) +
> sizeof(TEST_VAR_1_NAME);
>
> + DumpBuffer = AllocatePool( BufferSize );
>
> + UT_ASSERT_NOT_EQUAL( DumpBuffer, NULL );
>
> +
>
> + // Verify that the current table size is 0.
>
> + DumpSize = BufferSize;
>
> + UT_ASSERT_NOT_EFI_ERROR( DumpVariablePolicy( DumpBuffer,
> &DumpSize ) );
>
> + UT_ASSERT_EQUAL( DumpSize, 0 );
>
> +
>
> + // Now, set a new policy.
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &TestPolicy.Header ) );
>
> +
>
> + // Make sure that the new return is non-zero and fails as expected.
>
> + DumpSize = 0;
>
> + PolicyCheck = DumpVariablePolicy( NULL, &DumpSize );
>
> + UT_ASSERT_STATUS_EQUAL( PolicyCheck, EFI_BUFFER_TOO_SMALL );
>
> + UT_ASSERT_EQUAL( DumpSize, BufferSize );
>
> +
>
> + // Now verify that we can fetch the dump.
>
> + DumpSize = BufferSize;
>
> + UT_ASSERT_NOT_EFI_ERROR( DumpVariablePolicy( DumpBuffer,
> &DumpSize ) );
>
> + UT_ASSERT_EQUAL( DumpSize, BufferSize );
>
> + UT_ASSERT_MEM_EQUAL( &TestPolicy, DumpBuffer, BufferSize );
>
> +
>
> + // Always put away your toys.
>
> + FreePool( DumpBuffer );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +/**
>
> + Test Case
>
> +*/
>
> +UNIT_TEST_STATUS
>
> +EFIAPI
>
> +ShouldBeAbleToDumpThePolicyTableAfterDisabled (
>
> + IN UNIT_TEST_CONTEXT Context
>
> + )
>
> +{
>
> + SIMPLE_VARIABLE_POLICY_ENTRY TestPolicy = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_1_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_1,
>
> + TEST_POLICY_MIN_SIZE_10,
>
> + TEST_POLICY_MAX_SIZE_200,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_1_NAME
>
> + };
>
> + SIMPLE_VARIABLE_POLICY_ENTRY TestPolicy2 = {
>
> + {
>
> + VARIABLE_POLICY_ENTRY_REVISION,
>
> + sizeof(VARIABLE_POLICY_ENTRY) + sizeof(TEST_VAR_2_NAME),
>
> + sizeof(VARIABLE_POLICY_ENTRY),
>
> + TEST_GUID_2,
>
> + TEST_POLICY_MIN_SIZE_10,
>
> + TEST_POLICY_MAX_SIZE_200,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + TEST_POLICY_ATTRIBUTES_NULL,
>
> + VARIABLE_POLICY_TYPE_NO_LOCK
>
> + },
>
> + TEST_VAR_2_NAME
>
> + };
>
> + EFI_STATUS PolicyCheck;
>
> + UINT32 DumpSize;
>
> + VOID *DumpBuffer;
>
> +
>
> + DumpBuffer = NULL;
>
> + DumpSize = 0;
>
> +
>
> + // Register a new policy.
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &TestPolicy.Header ) );
>
> + // Make sure that we can dump the policy.
>
> + PolicyCheck = DumpVariablePolicy( DumpBuffer, &DumpSize );
>
> + UT_ASSERT_STATUS_EQUAL( PolicyCheck, EFI_BUFFER_TOO_SMALL );
>
> + DumpBuffer = AllocatePool( DumpSize );
>
> + UT_ASSERT_NOT_EFI_ERROR( DumpVariablePolicy( DumpBuffer,
> &DumpSize ) );
>
> + UT_ASSERT_MEM_EQUAL( DumpBuffer, &TestPolicy, DumpSize );
>
> +
>
> + // Clean up from this step.
>
> + FreePool( DumpBuffer );
>
> + DumpBuffer = NULL;
>
> + DumpSize = 0;
>
> +
>
> + // Now disable the engine.
>
> + DisableVariablePolicy();
>
> +
>
> + // Now register a new policy and make sure that both can be dumped.
>
> +
> UT_ASSERT_NOT_EFI_ERROR( RegisterVariablePolicy( &TestPolicy2.Header )
> );
>
> + // Make sure that we can dump the policy.
>
> + PolicyCheck = DumpVariablePolicy( DumpBuffer, &DumpSize );
>
> + UT_ASSERT_STATUS_EQUAL( PolicyCheck, EFI_BUFFER_TOO_SMALL );
>
> + DumpBuffer = AllocatePool( DumpSize );
>
> + UT_ASSERT_NOT_EFI_ERROR( DumpVariablePolicy( DumpBuffer,
> &DumpSize ) );
>
> +
>
> + // Finally, make sure that both policies are in the dump.
>
> + UT_ASSERT_MEM_EQUAL( DumpBuffer, &TestPolicy,
> TestPolicy.Header.Size );
>
> + UT_ASSERT_MEM_EQUAL( (UINT8*)DumpBuffer + TestPolicy.Header.Size,
>
> + &TestPolicy2,
>
> + TestPolicy2.Header.Size );
>
> +
>
> + // Always put away your toys.
>
> + FreePool( DumpBuffer );
>
> +
>
> + return UNIT_TEST_PASSED;
>
> +}
>
> +
>
> +
>
> +///=== TEST ENGINE
> ==========================================================
> ======================
>
> +
>
> +/**
>
> + SampleUnitTestApp
>
> +
>
> + @param[in] ImageHandle The firmware allocated handle for the EFI image.
>
> + @param[in] SystemTable A pointer to the EFI System Table.
>
> +
>
> + @retval EFI_SUCCESS The entry point executed successfully.
>
> + @retval other Some error occured when executing this entry point.
>
> +
>
> +**/
>
> +int
>
> +main (
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + UNIT_TEST_FRAMEWORK_HANDLE Framework = NULL;
>
> + UNIT_TEST_SUITE_HANDLE ArchTests;
>
> + UNIT_TEST_SUITE_HANDLE PolicyTests;
>
> + UNIT_TEST_SUITE_HANDLE UtilityTests;
>
> +#ifdef INTERNAL_UNIT_TEST
>
> + UNIT_TEST_SUITE_HANDLE InternalTests;
>
> +#endif // INTERNAL_UNIT_TEST
>
> +
>
> + DEBUG(( DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME,
> UNIT_TEST_VERSION ));
>
> +
>
> + //
>
> + // Start setting up the test framework for running the tests.
>
> + //
>
> + Status = InitUnitTestFramework( &Framework, UNIT_TEST_NAME,
> gEfiCallerBaseName, UNIT_TEST_VERSION );
>
> + if (EFI_ERROR( Status ))
>
> + {
>
> + DEBUG((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n",
> Status));
>
> + goto EXIT;
>
> + }
>
> +
>
> +
>
> + //
>
> + // Add all test suites and tests.
>
> + //
>
> + Status = CreateUnitTestSuite( &ArchTests, Framework, "Variable Policy
> Architectural Tests", "VarPolicy.Arch", NULL, NULL );
>
> + if (EFI_ERROR( Status ))
>
> + {
>
> + DEBUG((DEBUG_ERROR, "Failed in CreateUnitTestSuite for
> ArchTests\n"));
>
> + Status = EFI_OUT_OF_RESOURCES;
>
> + goto EXIT;
>
> + }
>
> + AddTestCase( ArchTests,
>
> + "Deinitialization should fail if not previously initialized",
> "VarPolicy.Arch.OnlyDeinit",
>
> + ShouldFailDeinitWithoutInit, NULL, NULL, NULL );
>
> + AddTestCase( ArchTests,
>
> + "Initialization followed by deinitialization should succeed",
> "VarPolicy.Arch.InitDeinit",
>
> + ShouldBeAbleToInitAndDeinitTheLibrary, NULL, NULL, NULL );
>
> + AddTestCase( ArchTests,
>
> + "The initialization function fail if called twice without a deinit",
> "VarPolicy.Arch.InitTwice",
>
> + ShouldNotBeAbleToInitializeTheLibraryTwice, NULL, LibCleanup,
> NULL );
>
> + AddTestCase( ArchTests,
>
> + "API functions should be unavailable until library is initialized",
> "VarPolicy.Arch.UninitApiOff",
>
> + ApiCommandsShouldNotRespondIfLibIsUninitialized, NULL,
> LibCleanup, NULL );
>
> +
>
> +#ifdef INTERNAL_UNIT_TEST
>
> + Status = CreateUnitTestSuite( &InternalTests, Framework, "Variable Policy
> Internal Tests", "VarPolicy.Internal", NULL, NULL );
>
> + if (EFI_ERROR( Status ))
>
> + {
>
> + DEBUG((DEBUG_ERROR, "Failed in CreateUnitTestSuite for
> InternalTests\n"));
>
> + Status = EFI_OUT_OF_RESOURCES;
>
> + goto EXIT;
>
> + }
>
> + AddTestCase( InternalTests,
>
> + "Policy matching should use name and GUID",
> "VarPolicy.Internal.NameGuid",
>
> + PoliciesShouldMatchByNameAndGuid, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( InternalTests,
>
> + "# sign wildcards should match digits",
> "VarPolicy.Internal.WildDigits",
>
> + WildcardPoliciesShouldMatchDigits, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( InternalTests,
>
> + "Digit wildcards should check edge cases",
> "VarPolicy.Internal.WildDigitsAdvanced",
>
> + WildcardPoliciesShouldMatchDigitsAdvanced, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( InternalTests,
>
> + "Empty names should match an entire namespace",
> "VarPolicy.Internal.WildNamespace",
>
> + WildcardPoliciesShouldMatchNamespaces, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( InternalTests,
>
> + "Match priority should weight correctly based on wildcards",
> "VarPolicy.Internal.Priorities",
>
> + MatchPrioritiesShouldFollowRules, LibInitMocked, LibCleanup,
> NULL );
>
> +#endif // INTERNAL_UNIT_TEST
>
> +
>
> + Status = CreateUnitTestSuite( &PolicyTests, Framework, "Variable Policy
> Manipulation Tests", "VarPolicy.Policy", NULL, NULL );
>
> + if (EFI_ERROR( Status ))
>
> + {
>
> + DEBUG((DEBUG_ERROR, "Failed in CreateUnitTestSuite for
> PolicyTests\n"));
>
> + Status = EFI_OUT_OF_RESOURCES;
>
> + goto EXIT;
>
> + }
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldAllowNamespaceWildcards",
> "VarPolicy.Policy.AllowNamespace",
>
> + RegisterShouldAllowNamespaceWildcards, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldAllowStateVarsForNamespaces",
> "VarPolicy.Policy.AllowStateNamespace",
>
> + RegisterShouldAllowStateVarsForNamespaces, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldRejectNullPointers", "VarPolicy.Policy.NullPointers",
>
> + RegisterShouldRejectNullPointers, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldRejectBadRevisions",
> "VarPolicy.Policy.BadRevisions",
>
> + RegisterShouldRejectBadRevisions, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldRejectBadSizes", "VarPolicy.Policy.BadSizes",
>
> + RegisterShouldRejectBadSizes, LibInitMocked, LibCleanup, NULL );
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldRejectBadOffsets", "VarPolicy.Policy.BadOffsets",
>
> + RegisterShouldRejectBadOffsets, LibInitMocked, LibCleanup, NULL );
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldRejectMissingStateStrings",
> "VarPolicy.Policy.MissingStateString",
>
> + RegisterShouldRejectMissingStateStrings, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldRejectStringsMissingNull",
> "VarPolicy.Policy.MissingNull",
>
> + RegisterShouldRejectStringsMissingNull, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldRejectMalformedStrings",
> "VarPolicy.Policy.MalformedStrings",
>
> + RegisterShouldRejectMalformedStrings, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldRejectUnpackedPolicies",
> "VarPolicy.Policy.PolicyPacking",
>
> + RegisterShouldRejectUnpackedPolicies, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldRejectInvalidNameCharacters",
> "VarPolicy.Policy.InvalidCharacters",
>
> + RegisterShouldRejectInvalidNameCharacters, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldRejectBadPolicyConstraints",
> "VarPolicy.Policy.BadConstraints",
>
> + RegisterShouldRejectBadPolicyConstraints, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldRejectUnknownLockPolicies",
> "VarPolicy.Policy.BadLocks",
>
> + RegisterShouldRejectUnknownLockPolicies, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldRejectPolicesWithTooManyWildcards",
> "VarPolicy.Policy.TooManyWildcards",
>
> + RegisterShouldRejectPolicesWithTooManyWildcards, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( PolicyTests,
>
> + "RegisterShouldRejectDuplicatePolicies",
> "VarPolicy.Policy.DuplicatePolicies",
>
> + RegisterShouldRejectDuplicatePolicies, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( PolicyTests,
>
> + "Variables that exceed min or max sizes should be rejected",
> "VarPolicy.Policy.MinMax",
>
> + MinAndMaxSizePoliciesShouldBeHonored, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( PolicyTests,
>
> + "AttributeMustPoliciesShouldBeHonored",
> "VarPolicy.Policy.AttrMust",
>
> + AttributeMustPoliciesShouldBeHonored, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( PolicyTests,
>
> + "AttributeCantPoliciesShouldBeHonored",
> "VarPolicy.Policy.AttrCant",
>
> + AttributeCantPoliciesShouldBeHonored, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( PolicyTests,
>
> + "VariablesShouldBeDeletableRegardlessOfSize",
> "VarPolicy.Policy.DeleteIgnoreSize",
>
> + VariablesShouldBeDeletableRegardlessOfSize, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( PolicyTests,
>
> + "LockNowPoliciesShouldBeHonored",
> "VarPolicy.Policy.VARIABLE_POLICY_TYPE_LOCK_NOW",
>
> + LockNowPoliciesShouldBeHonored, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( PolicyTests,
>
> + "LockOnCreatePoliciesShouldBeHonored",
> "VarPolicy.Policy.VARIABLE_POLICY_TYPE_LOCK_ON_CREATE",
>
> + LockOnCreatePoliciesShouldBeHonored, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( PolicyTests,
>
> + "LockOnStatePoliciesShouldBeHonored",
> "VarPolicy.Policy.LockState",
>
> + LockOnStatePoliciesShouldBeHonored, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( PolicyTests,
>
> + "LockOnStatePoliciesShouldApplyToNamespaces",
> "VarPolicy.Policy.NamespaceLockState",
>
> + LockOnStatePoliciesShouldApplyToNamespaces, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( PolicyTests,
>
> + "LockOnStateShouldHandleErrorsGracefully",
> "VarPolicy.Policy.LockStateErrors",
>
> + LockOnStateShouldHandleErrorsGracefully, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( PolicyTests,
>
> + "BestMatchPriorityShouldBeObeyed", "VarPolicy.Policy.BestMatch",
>
> + BestMatchPriorityShouldBeObeyed, LibInitMocked, LibCleanup,
> NULL );
>
> +
>
> + Status = CreateUnitTestSuite( &UtilityTests, Framework, "Variable Policy
> Utility Tests", "VarPolicy.Utility", NULL, NULL );
>
> + if (EFI_ERROR( Status ))
>
> + {
>
> + DEBUG((DEBUG_ERROR, "Failed in CreateUnitTestSuite for
> UtilityTests\n"));
>
> + Status = EFI_OUT_OF_RESOURCES;
>
> + goto EXIT;
>
> + }
>
> + AddTestCase( UtilityTests,
>
> + "API commands that change state should not respond after
> interface is locked", "VarPolicy.Utility.InterfaceLock",
>
> + ShouldBeAbleToLockInterface, LibInitMocked, LibCleanup, NULL );
>
> + AddTestCase( UtilityTests,
>
> + "All policies should pass once enforcement is disabled",
> "VarPolicy.Utility.DisableEnforcement",
>
> + ShouldBeAbleToDisablePolicyEnforcement, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( UtilityTests,
>
> + "Disabling enforcement twice should produce an error",
> "VarPolicy.Utility.DisableEnforcementTwice",
>
> + ShouldNotBeAbleToDisablePoliciesTwice, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( UtilityTests,
>
> + "ShouldBeAbleToAddNewPoliciesAfterDisabled",
> "VarPolicy.Utility.AddAfterDisable",
>
> + ShouldBeAbleToAddNewPoliciesAfterDisabled, LibInitMocked,
> LibCleanup, NULL );
>
> + AddTestCase( UtilityTests,
>
> + "ShouldBeAbleToLockAfterDisabled",
> "VarPolicy.Utility.LockAfterDisable",
>
> + ShouldBeAbleToLockAfterDisabled, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( UtilityTests,
>
> + "Should be able to dump the policy table",
> "VarPolicy.Utility.DumpTable",
>
> + ShouldBeAbleToDumpThePolicyTable, LibInitMocked, LibCleanup,
> NULL );
>
> + AddTestCase( UtilityTests,
>
> + "ShouldBeAbleToDumpThePolicyTableAfterDisabled",
> "VarPolicy.Utility.DumpTableAfterDisable",
>
> + ShouldBeAbleToDumpThePolicyTableAfterDisabled, LibInitMocked,
> LibCleanup, NULL );
>
> +
>
> +
>
> + //
>
> + // Execute the tests.
>
> + //
>
> + Status = RunAllTestSuites( Framework );
>
> +
>
> +EXIT:
>
> + if (Framework != NULL)
>
> + {
>
> + FreeUnitTestFramework( Framework );
>
> + }
>
> +
>
> + return Status;
>
> +}
>
> diff --git a/MdeModulePkg/Include/Library/VariablePolicyLib.h
> b/MdeModulePkg/Include/Library/VariablePolicyLib.h
> new file mode 100644
> index 000000000000..efd1840112ec
> --- /dev/null
> +++ b/MdeModulePkg/Include/Library/VariablePolicyLib.h
> @@ -0,0 +1,207 @@
> +/** @file -- VariablePolicyLib.h
>
> +Business logic for Variable Policy enforcement.
>
> +
>
> +Copyright (c) Microsoft Corporation.
>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#ifndef _VARIABLE_POLICY_LIB_H_
>
> +#define _VARIABLE_POLICY_LIB_H_
>
> +
>
> +#include <Protocol/VariablePolicy.h>
>
> +
>
> +/**
>
> + This API function validates and registers a new policy with
>
> + the policy enforcement engine.
>
> +
>
> + @param[in] NewPolicy Pointer to the incoming policy structure.
>
> +
>
> + @retval EFI_SUCCESS
>
> + @retval EFI_INVALID_PARAMETER NewPolicy is NULL or is internally
> inconsistent.
>
> + @retval EFI_ALREADY_STARTED An identical matching policy already
> exists.
>
> + @retval EFI_WRITE_PROTECTED The interface has been locked until
> the next reboot.
>
> + @retval EFI_UNSUPPORTED Policy enforcement has been disabled.
> No reason to add more policies.
>
> + @retval EFI_ABORTED A calculation error has prevented this
> function from completing.
>
> + @retval EFI_OUT_OF_RESOURCES Cannot grow the table to hold any
> more policies.
>
> + @retval EFI_NOT_READY Library has not yet been initialized.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +RegisterVariablePolicy (
>
> + IN CONST VARIABLE_POLICY_ENTRY *NewPolicy
>
> + );
>
> +
>
> +
>
> +/**
>
> + This API function checks to see whether the parameters to SetVariable
> would
>
> + be allowed according to the current variable policies.
>
> +
>
> + @param[in] VariableName Same as EFI_SET_VARIABLE.
>
> + @param[in] VendorGuid Same as EFI_SET_VARIABLE.
>
> + @param[in] Attributes Same as EFI_SET_VARIABLE.
>
> + @param[in] DataSize Same as EFI_SET_VARIABLE.
>
> + @param[in] Data Same as EFI_SET_VARIABLE.
>
> +
>
> + @retval EFI_SUCCESS A matching policy allows this update.
>
> + @retval EFI_SUCCESS There are currently no policies that restrict
> this update.
>
> + @retval EFI_SUCCESS The protections have been disable until the
> next reboot.
>
> + @retval EFI_WRITE_PROTECTED Variable is currently locked.
>
> + @retval EFI_INVALID_PARAMETER Attributes or size are invalid.
>
> + @retval EFI_ABORTED A lock policy exists, but an error prevented
> evaluation.
>
> + @retval EFI_NOT_READY Library has not been initialized.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +ValidateSetVariable (
>
> + IN CHAR16 *VariableName,
>
> + IN EFI_GUID *VendorGuid,
>
> + IN UINT32 Attributes,
>
> + IN UINTN DataSize,
>
> + IN VOID *Data
>
> + );
>
> +
>
> +
>
> +/**
>
> + This API function disables the variable policy enforcement. If it's
>
> + already been called once, will return EFI_ALREADY_STARTED.
>
> +
>
> + @retval EFI_SUCCESS
>
> + @retval EFI_ALREADY_STARTED Has already been called once this boot.
>
> + @retval EFI_WRITE_PROTECTED Interface has been locked until reboot.
>
> + @retval EFI_WRITE_PROTECTED Interface option is disabled by platform
> PCD.
>
> + @retval EFI_NOT_READY Library has not yet been initialized.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +DisableVariablePolicy (
>
> + VOID
>
> + );
>
> +
>
> +
>
> +/**
>
> + This API function will dump the entire contents of the variable policy table.
>
> +
>
> + Similar to GetVariable, the first call can be made with a 0 size and it will
> return
>
> + the size of the buffer required to hold the entire table.
>
> +
>
> + @param[out] Policy Pointer to the policy buffer. Can be NULL if Size is 0.
>
> + @param[in,out] Size On input, the size of the output buffer. On output,
> the size
>
> + of the data returned.
>
> +
>
> + @retval EFI_SUCCESS Policy data is in the output buffer and Size
> has been updated.
>
> + @retval EFI_INVALID_PARAMETER Size is NULL, or Size is non-zero and
> Policy is NULL.
>
> + @retval EFI_BUFFER_TOO_SMALL Size is insufficient to hold policy. Size
> updated with required size.
>
> + @retval EFI_NOT_READY Library has not yet been initialized.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +DumpVariablePolicy (
>
> + OUT UINT8 *Policy,
>
> + IN OUT UINT32 *Size
>
> + );
>
> +
>
> +
>
> +/**
>
> + This API function returns whether or not the policy engine is
>
> + currently being enforced.
>
> +
>
> + @retval TRUE
>
> + @retval FALSE
>
> + @retval FALSE Library has not yet been initialized.
>
> +
>
> +**/
>
> +BOOLEAN
>
> +EFIAPI
>
> +IsVariablePolicyEnabled (
>
> + VOID
>
> + );
>
> +
>
> +
>
> +/**
>
> + This API function locks the interface so that no more policy updates
>
> + can be performed or changes made to the enforcement until the next
> boot.
>
> +
>
> + @retval EFI_SUCCESS
>
> + @retval EFI_NOT_READY Library has not yet been initialized.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +LockVariablePolicy (
>
> + VOID
>
> + );
>
> +
>
> +
>
> +/**
>
> + This API function returns whether or not the policy interface is locked
>
> + for the remainder of the boot.
>
> +
>
> + @retval TRUE
>
> + @retval FALSE
>
> + @retval FALSE Library has not yet been initialized.
>
> +
>
> +**/
>
> +BOOLEAN
>
> +EFIAPI
>
> +IsVariablePolicyInterfaceLocked (
>
> + VOID
>
> + );
>
> +
>
> +
>
> +/**
>
> + This helper function initializes the library and sets
>
> + up any required internal structures or handlers.
>
> +
>
> + Also registers the internal pointer for the GetVariable helper.
>
> +
>
> + @param[in] GetVariableHelper A function pointer matching the
> EFI_GET_VARIABLE prototype that will be used to
>
> + check policy criteria that involve the existence of other variables.
>
> +
>
> + @retval EFI_SUCCESS
>
> + @retval EFI_ALREADY_STARTED The initialize function has been called
> more than once without a call to
>
> + deinitialize.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +InitVariablePolicyLib (
>
> + IN EFI_GET_VARIABLE GetVariableHelper
>
> + );
>
> +
>
> +
>
> +/**
>
> + This helper function returns whether or not the library is currently
> initialized.
>
> +
>
> + @retval TRUE
>
> + @retval FALSE
>
> +
>
> +**/
>
> +BOOLEAN
>
> +EFIAPI
>
> +IsVariablePolicyLibInitialized (
>
> + VOID
>
> + );
>
> +
>
> +
>
> +/**
>
> + This helper function tears down the library.
>
> +
>
> + Should generally only be used for test harnesses.
>
> +
>
> + @retval EFI_SUCCESS
>
> + @retval EFI_NOT_READY Deinitialize was called without first calling
> initialize.
>
> +
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +DeinitVariablePolicyLib (
>
> + VOID
>
> + );
>
> +
>
> +
>
> +#endif // _VARIABLE_POLICY_LIB_H_
>
> diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
> new file mode 100644
> index 000000000000..f4a879d5382f
> --- /dev/null
> +++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
> @@ -0,0 +1,44 @@
> +## @file VariablePolicyLib.inf
>
> +# Business logic for Variable Policy enforcement.
>
> +#
>
> +##
>
> +# Copyright (c) Microsoft Corporation.
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +##
>
> +
>
> +
>
> +[Defines]
>
> + INF_VERSION = 0x00010017
>
> + BASE_NAME = VariablePolicyLib
>
> + FILE_GUID = E9ECD342-159A-4F24-9FDF-65724027C594
>
> + VERSION_STRING = 1.0
>
> + MODULE_TYPE = DXE_DRIVER
>
> + LIBRARY_CLASS = VariablePolicyLib|DXE_DRIVER DXE_SMM_DRIVER
> MM_STANDALONE
>
> +
>
> +#
>
> +# The following information is for reference only and not required by the
> build tools.
>
> +#
>
> +# VALID_ARCHITECTURES = ANY
>
> +#
>
> +
>
> +
>
> +[Sources]
>
> + VariablePolicyLib.c
>
> + VariablePolicyExtraInitNull.c
>
> +
>
> +
>
> +[Packages]
>
> + MdePkg/MdePkg.dec
>
> + MdeModulePkg/MdeModulePkg.dec
>
> +
>
> +
>
> +[LibraryClasses]
>
> + DebugLib
>
> + BaseMemoryLib
>
> + MemoryAllocationLib
>
> + SafeIntLib
>
> + PcdLib
>
> +
>
> +
>
> +[Pcd]
>
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDis
> able ## CONSUMES
>
> diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni
> new file mode 100644
> index 000000000000..2227ec427828
> --- /dev/null
> +++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni
> @@ -0,0 +1,12 @@
> +// /** @file
>
> +// VariablePolicyLib.uni
>
> +//
>
> +// Copyright (c) Microsoft Corporation.
>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +//
>
> +// **/
>
> +
>
> +
>
> +#string STR_MODULE_ABSTRACT #language en-US "Library containing
> the business logic for the VariablePolicy engine"
>
> +
>
> +#string STR_MODULE_DESCRIPTION #language en-US "Library
> containing the business logic for the VariablePolicy engine"
>
> diff --git
> a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.in
> f
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.in
> f
> new file mode 100644
> index 000000000000..8b8365741864
> --- /dev/null
> +++
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.in
> f
> @@ -0,0 +1,51 @@
> +## @file VariablePolicyLibRuntimeDxe.inf
>
> +# Business logic for Variable Policy enforcement.
>
> +# This instance is specifically for RuntimeDxe and contains
>
> +# extra routines to register for VirtualAddressChangeEvents.
>
> +#
>
> +# Copyright (c) Microsoft Corporation.
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +##
>
> +
>
> +
>
> +[Defines]
>
> + INF_VERSION = 0x00010017
>
> + BASE_NAME = VariablePolicyLibRuntimeDxe
>
> + FILE_GUID = 205F7F0E-8EAC-4914-8390-1B90DD7E2A27
>
> + VERSION_STRING = 1.0
>
> + MODULE_TYPE = DXE_RUNTIME_DRIVER
>
> + LIBRARY_CLASS = VariablePolicyLib|DXE_RUNTIME_DRIVER
>
> +
>
> +#
>
> +# The following information is for reference only and not required by the
> build tools.
>
> +#
>
> +# VALID_ARCHITECTURES = ANY
>
> +#
>
> +
>
> +
>
> +[Sources]
>
> + VariablePolicyLib.c
>
> + VariablePolicyExtraInitRuntimeDxe.c
>
> +
>
> +
>
> +[Packages]
>
> + MdePkg/MdePkg.dec
>
> + MdeModulePkg/MdeModulePkg.dec
>
> +
>
> +
>
> +[LibraryClasses]
>
> + DebugLib
>
> + BaseMemoryLib
>
> + MemoryAllocationLib
>
> + SafeIntLib
>
> + UefiBootServicesTableLib
>
> + UefiRuntimeServicesTableLib
>
> + PcdLib
>
> +
>
> +
>
> +[Pcd]
>
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDis
> able ## CONSUMES
>
> +
>
> +
>
> +[Guids]
>
> + gEfiEventVirtualAddressChangeGuid
>
> diff --git
> a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/Variable
> PolicyUnitTest.inf
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/Variable
> PolicyUnitTest.inf
> new file mode 100644
> index 000000000000..ccc04bb600d6
> --- /dev/null
> +++
> b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/Variable
> PolicyUnitTest.inf
> @@ -0,0 +1,40 @@
> +## @file VariablePolicyUnitTest.inf
>
> +# UnitTest for...
>
> +# Business logic for Variable Policy enforcement.
>
> +#
>
> +# Copyright (c) Microsoft Corporation.
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +##
>
> +
>
> +
>
> +[Defines]
>
> + INF_VERSION = 0x00010006
>
> + BASE_NAME = VariablePolicyUnitTest
>
> + FILE_GUID = 1200A2E4-D756-418C-9768-528C2D181A98
>
> + MODULE_TYPE = HOST_APPLICATION
>
> + VERSION_STRING = 1.0
>
> +
>
> +#
>
> +# The following information is for reference only and not required by the
> build tools.
>
> +#
>
> +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
>
> +#
>
> +
>
> +[Sources]
>
> + VariablePolicyUnitTest.c
>
> +
>
> +
>
> +[Packages]
>
> + MdePkg/MdePkg.dec
>
> + MdeModulePkg/MdeModulePkg.dec
>
> + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
>
> +
>
> +
>
> +[LibraryClasses]
>
> + BaseLib
>
> + DebugLib
>
> + UnitTestLib
>
> + PrintLib
>
> + VariablePolicyLib
>
> + BaseMemoryLib
>
> + MemoryAllocationLib
>
> diff --git a/MdeModulePkg/MdeModulePkg.dec
> b/MdeModulePkg/MdeModulePkg.dec
> index 05d8ad4931f9..0b58c14e4747 100644
> --- a/MdeModulePkg/MdeModulePkg.dec
> +++ b/MdeModulePkg/MdeModulePkg.dec
> @@ -31,6 +31,9 @@ [LibraryClasses]
> ## @libraryclass Defines a set of methods to reset whole system.
>
> ResetSystemLib|Include/Library/ResetSystemLib.h
>
>
>
> + ## @libraryclass Business logic for storing and testing variable policies
>
> + VariablePolicyLib|Include/Library/VariablePolicyLib.h
>
> +
>
> ## @libraryclass Defines a set of helper functions for resetting the system.
>
> ResetUtilityLib|Include/Library/ResetUtilityLib.h
>
>
>
> diff --git a/MdeModulePkg/MdeModulePkg.dsc
> b/MdeModulePkg/MdeModulePkg.dsc
> index 25aea3e2a481..14b6ed536962 100644
> --- a/MdeModulePkg/MdeModulePkg.dsc
> +++ b/MdeModulePkg/MdeModulePkg.dsc
> @@ -3,6 +3,7 @@
> #
>
> # (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
>
> # Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
>
> +# Copyright (c) Microsoft Corporation.
>
> #
>
> # SPDX-License-Identifier: BSD-2-Clause-Patent
>
> #
>
> @@ -58,6 +59,7 @@ [LibraryClasses]
> DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
>
>
> DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTabl
> eLib.inf
>
>
> UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBoo
> tManagerLib.inf
>
> +
> VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLi
> b.inf
>
> #
>
> # Generic Modules
>
> #
>
> @@ -129,6 +131,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
> DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
>
>
> LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.in
> f
>
>
> CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsule
> Lib.inf
>
> +
> VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLi
> bRuntimeDxe.inf
>
>
>
> [LibraryClasses.common.SMM_CORE]
>
> HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
>
> @@ -306,6 +309,8 @@ [Components]
> MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
>
>
> MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull
> .inf
>
> MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
>
> + MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
>
> +
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
>
> MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
>
> MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf
>
> MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf
>
> diff --git a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
> b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
> index 72a119db4568..095e613f1be1 100644
> --- a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
> +++ b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc
> @@ -19,12 +19,23 @@ [Defines]
>
>
> !include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
>
>
>
> +[LibraryClasses]
>
> + SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
>
> +
>
> [Components]
>
>
> MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeSer
> vicesTableLib.inf
>
>
>
> #
>
> # Build MdeModulePkg HOST_APPLICATION Tests
>
> #
>
> +
> MdeModulePkg/Library/VariablePolicyLib/VariablePolicyUnitTest/VariablePo
> licyUnitTest.inf {
>
> + <LibraryClasses>
>
> +
> VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLi
> b.inf
>
> +
>
> + <PcdsFixedAtBuild>
>
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDis
> able|TRUE
>
> + }
>
> +
>
>
> MdeModulePkg/Library/DxeResetSystemLib/UnitTest/DxeResetSystemLibU
> nitTestHost.inf {
>
> <LibraryClasses>
>
>
> ResetSystemLib|MdeModulePkg/Library/DxeResetSystemLib/DxeResetSyst
> emLib.inf
>
> --
> 2.26.2.windows.1.8.g01c50adf56.20200515075929
>
>
> -=-=-=-=-=-=
> Groups.io Links: You receive all messages sent to this group.
>
> View/Reply Online (#61588): https://edk2.groups.io/g/devel/message/61588
> Mute This Topic: https://groups.io/mt/75057697/1768738
> Group Owner: devel+owner@edk2.groups.io
> Unsubscribe: https://edk2.groups.io/g/devel/unsub [dandan.bi@intel.com]
> -=-=-=-=-=-=
next prev parent reply other threads:[~2020-07-02 2:13 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-23 6:40 [PATCH v6 00/14] Add the VariablePolicy feature bret
2020-06-23 6:40 ` [PATCH v6 01/14] MdeModulePkg: Define the VariablePolicy protocol interface Bret Barkelew
2020-06-23 6:40 ` [PATCH v6 02/14] MdeModulePkg: Define the VariablePolicyLib Bret Barkelew
2020-07-02 2:13 ` Dandan Bi [this message]
2020-07-02 7:16 ` [edk2-devel] " Bret Barkelew
2020-06-23 6:40 ` [PATCH v6 03/14] MdeModulePkg: Define the VariablePolicyHelperLib Bret Barkelew
2020-06-23 6:40 ` [PATCH v6 04/14] MdeModulePkg: Define the VarCheckPolicyLib and SMM interface Bret Barkelew
2020-07-02 2:13 ` [edk2-devel] " Dandan Bi
2020-07-02 6:41 ` Bret Barkelew
2020-06-23 6:40 ` [PATCH v6 05/14] OvmfPkg: Add VariablePolicy engine to OvmfPkg platform Bret Barkelew
2020-06-23 6:40 ` [PATCH v6 06/14] EmulatorPkg: Add VariablePolicy engine to EmulatorPkg platform Bret Barkelew
2020-06-23 6:40 ` [PATCH v6 07/14] ArmVirtPkg: Add VariablePolicy engine to ArmVirtPkg platform Bret Barkelew
2020-06-23 6:40 ` [PATCH v6 08/14] UefiPayloadPkg: Add VariablePolicy engine to UefiPayloadPkg platform Bret Barkelew
2020-06-23 16:45 ` Ma, Maurice
2020-06-23 6:40 ` [PATCH v6 09/14] MdeModulePkg: Connect VariablePolicy business logic to VariableServices Bret Barkelew
2020-07-02 2:13 ` [edk2-devel] " Dandan Bi
2020-07-02 6:40 ` Bret Barkelew
2020-06-23 6:41 ` [PATCH v6 10/14] MdeModulePkg: Allow VariablePolicy state to delete protected variables Bret Barkelew
2020-06-23 6:41 ` [PATCH v6 11/14] SecurityPkg: Allow VariablePolicy state to delete authenticated variables Bret Barkelew
2020-06-23 6:41 ` [PATCH v6 12/14] MdeModulePkg: Change TCG MOR variables to use VariablePolicy Bret Barkelew
2020-06-23 6:41 ` [PATCH v6 13/14] MdeModulePkg: Drop VarLock from RuntimeDxe variable driver Bret Barkelew
2020-07-02 2:13 ` [edk2-devel] " Dandan Bi
2020-07-02 6:36 ` Bret Barkelew
2020-06-23 6:41 ` [PATCH v6 14/14] MdeModulePkg: Add a shell-based functional test for VariablePolicy Bret Barkelew
2020-07-02 2:13 ` [edk2-devel] [PATCH v6 00/14] Add the VariablePolicy feature Dandan Bi
2020-07-02 6:45 ` Bret Barkelew
2020-07-02 6:47 ` Bret Barkelew
2020-07-02 11:06 ` Laszlo Ersek
2020-07-02 18:26 ` [EXTERNAL] " Bret Barkelew
2020-07-29 19:56 ` [EXTERNAL] " Bret Barkelew
2020-07-30 1:36 ` Liming Gao
2020-07-30 1:43 ` Bret Barkelew
[not found] ` <161DCDB779DB4B3C.30988@groups.io>
2020-08-11 13:52 ` Dandan Bi
2020-08-18 5:24 ` Bret Barkelew
[not found] ` <162C456ABCC01019.19371@groups.io>
2020-08-26 6:49 ` Bret Barkelew
[not found] ` <162EBEB1FCE1A80C.27554@groups.io>
2020-09-08 22:20 ` Bret Barkelew
2020-09-09 0:41 ` 回复: " gaoliming
[not found] ` <1632EF0542479E7A.4657@groups.io>
2020-09-11 15:18 ` Bret Barkelew
2020-09-11 16:43 ` Laszlo Ersek
2020-09-14 6:42 ` Wang, Jian J
2020-09-15 20:51 ` Bret Barkelew
2020-09-16 0:54 ` 回复: " gaoliming
2020-09-16 1:05 ` Yao, Jiewen
2020-09-16 1:37 ` 回复: " gaoliming
2020-09-16 1:43 ` Yao, Jiewen
2020-09-16 1:44 ` Bret Barkelew
[not found] ` <16351037402D5209.16285@groups.io>
2020-09-18 6:55 ` Bret Barkelew
[not found] ` <1635CE5BD52DF579.6413@groups.io>
2020-09-22 2:50 ` Bret Barkelew
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=BN6PR11MB1393421389F91E0633D430BBEA6D0@BN6PR11MB1393.namprd11.prod.outlook.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox