1. Done 2. Done 3. BestResult can’t be anything but NULL if MatchPriority isn’t initialized, so the second half of this will never be evaluated, but I see your point. I’ve added a default initialization for the variable. 4. Done Thanks! - Bret From: Dandan Bi via groups.io Sent: Wednesday, July 1, 2020 7:13 PM To: devel@edk2.groups.io; bret@corthon.com Cc: Wang, Jian J; Wu, Hao A; liming.gao Subject: [EXTERNAL] Re: [edk2-devel] [PATCH v6 02/14] MdeModulePkg: Define the VariablePolicyLib 4 comments inline, please check. Thanks, Dandan > -----Original Message----- > From: 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 ; Wu, Hao A ; > Gao, Liming > Subject: [edk2-devel] [PATCH v6 02/14] MdeModulePkg: Define the > VariablePolicyLib > > https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2522&data=02%7C01%7Cbret.barkelew%40microsoft.com%7C4ff781c598384282187708d81e2d8858%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637292528218882209&sdata=cw75EiZAUXPo9iwbbkXrZwoLpuv1F7rHZIiDDHSToDA%3D&reserved=0 > > 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 > Cc: Hao A Wu > Cc: Liming Gao > Cc: Bret Barkelew > Signed-off-by: Bret Barkelew > --- > 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 > > + > > + > > +/** > > + 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 > > +#include > > + > > +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 > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > +#include > > + > > + > > +// 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 > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include > > + > > +#include > > +#include > > + > > +// 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 > > + > > +/** > > + 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.
> > # Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.
> > +# 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 { > > + > > + > VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLi > b.inf > > + > > + > > + > gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDis > able|TRUE > > + } > > + > > > MdeModulePkg/Library/DxeResetSystemLib/UnitTest/DxeResetSystemLibU > nitTestHost.inf { > > > > > 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://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F61588&data=02%7C01%7Cbret.barkelew%40microsoft.com%7C4ff781c598384282187708d81e2d8858%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637292528218892203&sdata=LU1JPSqqPVToubD2UJd8JT34dvLGJ6QSi7oA7s%2FyiqY%3D&reserved=0 > Mute This Topic: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgroups.io%2Fmt%2F75057697%2F1768738&data=02%7C01%7Cbret.barkelew%40microsoft.com%7C4ff781c598384282187708d81e2d8858%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637292528218892203&sdata=Y%2BAVPkeX7Clj7g0E0ENKDcJQwVksMtp%2FbZjBgDdz%2B1A%3D&reserved=0 > Group Owner: devel+owner@edk2.groups.io > Unsubscribe: https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Funsub&data=02%7C01%7Cbret.barkelew%40microsoft.com%7C4ff781c598384282187708d81e2d8858%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637292528218892203&sdata=Qzd%2FXa8ldydS45UAIyd7PaGORBzcESMWbNT1oUNEZm4%3D&reserved=0 [dandan.bi@intel.com] > -=-=-=-=-=-=