From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (NAM10-BN7-obe.outbound.protection.outlook.com [40.107.92.135]) by mx.groups.io with SMTP id smtpd.web10.2560.1592379444485961848 for ; Wed, 17 Jun 2020 00:37:25 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@microsoft.com header.s=selector2 header.b=MGcG3Zd0; spf=pass (domain: microsoft.com, ip: 40.107.92.135, mailfrom: bret.barkelew@microsoft.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Ikt2MymBPauVW7HQfcXUnn2NcjVpSke3nqnNY8XG4dIuQkXVfHnAlmWzRjN4WzrUVQaoEyv2fbmixZwLJbCz6QZKgL4UyNThU7MeSvyLUBOwxLFEEyCbwM0SW903+sxZ+Z7gche+AzpVgENZ9T/GATitKsvWo6eIy2bb/yS5OEUylTwFTflI+irTFdTs35/yO/DlkE2VWasXKpDY6YMVOp3mvoWRxBICb0Lk0VonMxKqvBE39ZmeKBpntL/XDHRNmd3n+5J7ev3/vU9SH5OmZA39xvZ6eSQ682OnnLSAkiGwQXEcBi6OlxnCpiSRHoHUG/CrXKC3dlI700I4pBcqWQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=FSmb5v3rGJ7byxKI31jAkFfAVLpFmYLWny3zZHBDUD4=; b=IJfIcpUpck+12WOlgHtSB09UR7/Eat9u0ObsX56GQZLnDaMCEnpRK4xLkVH7TyVo7oJnZSKd5kkGTYTJod5uI5pKjCFqnh78bZzrWl8AxhrdrsmXgsSyHlffQKnTL40YyBtJXk6uMhgU4OEM4nGG5Bc5KlhXyMf9zMOZIctKZSlGXxfoGx1bW/JXLa5N6Bf/2KUbwj4uu3NVlhkbyxL0THx00TuTY+7+xTTG7flPEVMfCA44JRfZ6we68fdQoJvI6nBo8MGht0wdI+NJp5TK/d7HJfBdSw7vqDeu8fAZ35xaP6D3wI6KypvqtLf8PyshkS4CqMwhyip+nRAqxSa6fA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=microsoft.com; dmarc=pass action=none header.from=microsoft.com; dkim=pass header.d=microsoft.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=FSmb5v3rGJ7byxKI31jAkFfAVLpFmYLWny3zZHBDUD4=; b=MGcG3Zd0CyEK8RkiE2Mm2SSL65Ki2ieReYraj9Yevv3SGlQF3260tc58gwVQJZhSfUG33qUkGYkWNsupjO3hbYQ88KI2dBx/ERomCOpgZvxMmX0R1dHVcFgrs/z7soK4bV+WhUgpY70e6Wk782TnRzsQSUXb72d9HwlEW7+dCzA= Received: from CY4PR21MB0743.namprd21.prod.outlook.com (2603:10b6:903:b2::9) by CY4PR2101MB0865.namprd21.prod.outlook.com (2603:10b6:910:8a::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3131.9; Wed, 17 Jun 2020 07:37:21 +0000 Received: from CY4PR21MB0743.namprd21.prod.outlook.com ([fe80::4ef:d9e:62c:f319]) by CY4PR21MB0743.namprd21.prod.outlook.com ([fe80::f112:82fb:d4fd:f7dd%10]) with mapi id 15.20.3131.009; Wed, 17 Jun 2020 07:37:21 +0000 From: "Bret Barkelew" To: "devel@edk2.groups.io" , "bret@corthon.com" CC: Jian J Wang , Hao A Wu , liming.gao Subject: Re: [EXTERNAL] [edk2-devel] [PATCH v5 14/14] MdeModulePkg: Add a shell-based functional test for VariablePolicy Thread-Topic: [EXTERNAL] [edk2-devel] [PATCH v5 14/14] MdeModulePkg: Add a shell-based functional test for VariablePolicy Thread-Index: AQHWOYzCS/zANBAd0karFSwjRdP4C6jcgSZs Date: Wed, 17 Jun 2020 07:37:21 +0000 Message-ID: References: <20200603065810.806-1-brbarkel@microsoft.com>,<20200603065810.806-15-brbarkel@microsoft.com> In-Reply-To: <20200603065810.806-15-brbarkel@microsoft.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Enabled=True;MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SiteId=72f988bf-86f1-41af-91ab-2d7cd011db47;MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SetDate=2020-06-17T07:37:18.791Z;MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Name=General;MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_ContentBits=0;MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Method=Standard; authentication-results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=microsoft.com; x-originating-ip: [71.212.143.8] x-ms-publictraffictype: Email x-ms-office365-filtering-ht: Tenant x-ms-office365-filtering-correlation-id: ad68064a-eda9-4f42-fc03-08d81291453a x-ms-traffictypediagnostic: CY4PR2101MB0865: x-ld-processed: 72f988bf-86f1-41af-91ab-2d7cd011db47,ExtAddr x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:10000; x-forefront-prvs: 04371797A5 x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: O8JbVcXuDtGiic7aJ4WnfGZLT6uVSoLToxdOokh2GDjG5eT1iNjkPCsUXZbKiCFk/+PY7bsnsafsMRzXRVQNToCDW30EcUTDWZIGaOYzw55c8BkLRVKqQ81x2GCEnKOTnrNMfnJ2CqmLZ9xJKLWLGyI7rBUYnAYW0ZCiKCkSgNBjwqy42yKLdq8b8xwDc1NjYUByg2Ioej4DDOgCjNNhqsYd2TZxX5o2yHWQOte51/LD8xiV8kE/agK6zqUgJArJ0PGCsEsG3PtCLxoyVvW8GY2/h6aOVdxnmdr5+wqrk4qWEw588pTVhtwH2XwMShRztmH5ER2Mt/6p0VAWeQUbVwX7X/vH3CwRvSrpbcfFoMRlCM3AiEY5cY1EO8C5IJK7qLidVSn4JDLH5ubsTYrXgfDSmakELG2D7qiE0qSm8BY0CCrrW7Bx9ZfUTkIOx0Kn x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY4PR21MB0743.namprd21.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(4636009)(396003)(366004)(376002)(39860400002)(346002)(136003)(91956017)(76116006)(66446008)(66946007)(64756008)(66476007)(66556008)(82950400001)(82960400001)(30864003)(5660300002)(166002)(7696005)(52536014)(110136005)(54906003)(33656002)(19627235002)(71200400001)(83380400001)(966005)(478600001)(2906002)(53546011)(8676002)(8990500004)(26005)(10290500003)(55016002)(186003)(4326008)(6506007)(8936002)(9686003)(316002)(19627405001)(86362001)(579004)(559001)(569008);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: 1+JlXAoZ9ovmNM1TeFdIrxOB8ZHzHHrDdW+0Y5fFNwQF2trasAuOyy4VjP4aAsWxTT8xKZ6smd/rMvPnGmpYP8zbWnuMj4ykaPQ5tLce2CG/Fi+400URJxlI3u/JWhLaeXQ2cla+oWNy2oU+m4B39uS1RBsQjT0PhAV40PHVOJN1iA65dnTgMPpjaDr5DPLM6CBl5g6crNIIAWnBoI+9zHxccrc/iNflFeVIfC057QXsUAYi4I4O+7R3kO31g7d6OoWMWI9rBXC79jdHgj9ltETJsiDiCNf1T0si0X8btvAI6lGOUEmJXMgIMcw0lx0UOIYdtajowCwmI40wJGqLEQFlfNpBHmoOntc2tb9CGi5ziShjUN8qhk2jMSZ42KIbTdjUsHPEtD+sPPrty6u/lME6i5GAv1uqVCNDiwliVND+rj3/kGCqbBxO9zPDhDQuYuLP6/Tfp9vZ24xXjj84u7pceRvqUKaAR4MmxNdiCPM= x-ms-exchange-transport-forked: True MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CY4PR21MB0743.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: ad68064a-eda9-4f42-fc03-08d81291453a X-MS-Exchange-CrossTenant-originalarrivaltime: 17 Jun 2020 07:37:21.2797 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: nLYM3ar/mpQIP++H5v/H8/nNLZqAa6BWQapex78GAUFxmk3a3XJl+70yacXQQHSsyhJnvmbTjgdj5d/GhPjWJg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR2101MB0865 Content-Language: en-US Content-Type: multipart/alternative; boundary="_000_CY4PR21MB07431BB6A62B00E160B57138EF9A0CY4PR21MB0743namp_" --_000_CY4PR21MB07431BB6A62B00E160B57138EF9A0CY4PR21MB0743namp_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Bump. This specific patch needs Reviews. - Bret ________________________________ From: devel@edk2.groups.io on behalf of Bret Barkele= w via groups.io Sent: Tuesday, June 2, 2020 11:58 PM To: devel@edk2.groups.io Cc: Jian J Wang ; Hao A Wu ; lim= ing.gao Subject: [EXTERNAL] [edk2-devel] [PATCH v5 14/14] MdeModulePkg: Add a shell= -based functional test for VariablePolicy https://nam06.safelinks.protection.outlook.com/?url=3Dhttps%3A%2F%2Fbugzill= a.tianocore.org%2Fshow_bug.cgi%3Fid%3D2522&data=3D02%7C01%7Cbret.barkel= ew%40microsoft.com%7C48059bf775454b7b4d2608d807a3e308%7C72f988bf86f141af91a= b2d7cd011db47%7C1%7C0%7C637267747768910602&sdata=3D7sdOwPRBe3bmI19WebIF= lV5EgEF0z%2FkNunFwPnAhXj4%3D&reserved=3D0 To verify that VariablePolicy is correctly integrated on platforms, add a Shell-based functional test to confirm expected behavior. NOTE: This test assumes that VariablePolicy is built with PcdAllowVariablePolicyEnforcementDisable set to TRUE. Cc: Jian J Wang Cc: Hao A Wu Cc: Liming Gao Cc: Bret Barkelew Signed-off-by: Bret Barkelew --- MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTe= stApp.c | 1978 ++++++++++++++++++++ MdeModulePkg/MdeModulePkg.ci.yaml = | 4 +- MdeModulePkg/MdeModulePkg.dsc = | 6 + MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md = | 55 + MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTe= stApp.inf | 42 + 5 files changed, 2084 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Variable= PolicyFuncTestApp.c b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp= /VariablePolicyFuncTestApp.c new file mode 100644 index 000000000000..e41b6e7a43d5 --- /dev/null +++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyF= uncTestApp.c @@ -0,0 +1,1978 @@ +/** @file +UEFI Shell based application for unit testing the Variable Policy Protocol= . + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// TODO: Need to add to the UnitTestFrameworkPkg +// #include + +#define UNIT_TEST_APP_NAME "Variable Policy Unit Test Application" +#define UNIT_TEST_APP_VERSION "0.1" + +// TODO: Need to add to the UnitTestFrameworkPkg +UNIT_TEST_FRAMEWORK_HANDLE +GetActiveFrameworkHandle ( + VOID + ); + +EDKII_VARIABLE_POLICY_PROTOCOL *mVarPol =3D NULL; + + +EFI_GUID mTestNamespaceGuid1 =3D { 0x3b389299, 0xabaf, 0x433b, { 0xa4, 0xa= 9, 0x23, 0xc8, 0x44, 0x02, 0xfc, 0xad } }; +EFI_GUID mTestNamespaceGuid2 =3D { 0x4c49a3aa, 0xbcb0, 0x544c, { 0xb5, 0xb= a, 0x34, 0xd9, 0x55, 0x13, 0x0d, 0xbe } }; +EFI_GUID mTestNamespaceGuid3 =3D { 0x5d5ab4bb, 0xcdc1, 0x655d, { 0xc6, 0xc= b, 0x45, 0xea, 0x66, 0x24, 0x1e, 0xcf } }; + +/** + Prerequisite for most test cases. +**/ +UNIT_TEST_STATUS +EFIAPI +LocateVarPolicyPreReq ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + if (mVarPol =3D=3D NULL) { + Status =3D gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, + NULL, + (VOID **) &mVarPol); + UT_ASSERT_NOT_EFI_ERROR (Status); + UT_ASSERT_NOT_NULL (mVarPol); + } + + return UNIT_TEST_PASSED; + +} // LocateVarPolicyPreReq + +/** + Getting Started tests. +**/ +UNIT_TEST_STATUS +EFIAPI +CheckVpEnabled ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + BOOLEAN State; + + Status =3D mVarPol->IsVariablePolicyEnabled (&State); + + UT_ASSERT_NOT_EFI_ERROR (Status); + UT_ASSERT_EQUAL (State, TRUE); + + return UNIT_TEST_PASSED; +} // CheckVpEnabled + +UNIT_TEST_STATUS +EFIAPI +CheckVpRevision ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UT_ASSERT_NOT_EQUAL (mVarPol->Revision, 0); + UT_LOG_INFO ("VP Revision: 0x%x\n", mVarPol->Revision); + + return UNIT_TEST_PASSED; +} // CheckVpRevision + +/** + NoLock Policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestMinSizeNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value1; + UINT32 Value2; + UINT8 *Buffer; + + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"MinSizeNoLockVar", + 4, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that is smaller than minsize + // + Value1 =3D 0x12; + Status =3D gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS), + sizeof (Value1), + &Value1); + UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status =3D=3D EF= I_INVALID_PARAMETER)); + + // + // Try to write a var of size that matches minsize + // + Value2 =3D 0xa1b2c3d4; + Status =3D gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS), + sizeof (Value2), + &Value2); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status =3D gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size larger than minsize + // + Buffer =3D AllocateZeroPool (40); + UT_ASSERT_NOT_NULL (Buffer); + Status =3D gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS), + 40, + Buffer); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Delete the variable + // + Status =3D gRT->SetVariable (L"MinSizeNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + FreePool (Buffer); + + return UNIT_TEST_PASSED; +} // TestMinSizeNoLock + +UNIT_TEST_STATUS +EFIAPI +TestMaxSizeNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value1; + UINT32 Value2; + UINT8 *Buffer; + + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"MaxSizeNoLockVar", + VARIABLE_POLICY_NO_MIN_SIZE, + 4, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that is smaller than maxsize + // + Value1 =3D 0x34; + Status =3D gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS), + sizeof (Value1), + &Value1); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status =3D gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size that matches maxsize + // + Value2 =3D 0xa1b2c3d4; + Status =3D gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS), + sizeof (Value2), + &Value2); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status =3D gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size larger than maxsize + // + Buffer =3D AllocateZeroPool (40); + UT_ASSERT_NOT_NULL (Buffer); + Status =3D gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS), + 40, + Buffer); + UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status =3D=3D EF= I_INVALID_PARAMETER)); + + FreePool (Buffer); + + return UNIT_TEST_PASSED; +} // TestMaxSizeNoLock + +UNIT_TEST_STATUS +EFIAPI +TestMustHaveAttrNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"MustHaveAttrNoLockVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + (EFI_VARIABLE_NON_VOLATILE | EFI_= VARIABLE_BOOTSERVICE_ACCESS), + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that doesn't have the must-have attributes + // + Value =3D 0x56; + Status =3D gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (Value), + &Value); + UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status =3D=3D EF= I_INVALID_PARAMETER)); + + // + // Try to write a var that has exactly the required attributes + // + Status =3D gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // NOTE: some implementations of VP will require the musthave attributes= to be passed even when deleting + // + Status =3D gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that has the required attributes and one extra att= ribute + // + Status =3D gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // NOTE: some implementations of VP will require the musthave attributes= to be passed even when deleting + // + Status =3D gRT->SetVariable (L"MustHaveAttrNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + return UNIT_TEST_PASSED; +} // TestMustHaveAttrNoLock + +UNIT_TEST_STATUS +EFIAPI +TestCantHaveAttrNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"CantHaveAttrNoLockVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + EFI_VARIABLE_NON_VOLATILE, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that has a can't have attr + // + Value =3D 0x78; + Status =3D gRT->SetVariable (L"CantHaveAttrNoLockVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status =3D=3D EF= I_INVALID_PARAMETER)); + + // + // Try to write a var that satisfies the can't have requirement + // + Status =3D gRT->SetVariable (L"CantHaveAttrNoLockVar", + &mTestNamespaceGuid1, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status =3D gRT->SetVariable (L"CantHaveAttrNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestCantHaveAttrNoLock + +UNIT_TEST_STATUS +EFIAPI +TestMaxSizeNamespaceNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value1; + UINT32 Value2; + UINT8 *Buffer; + + // + // Register a namespace-wide policy limiting max size to 4 bytes + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid2, + NULL, + VARIABLE_POLICY_NO_MIN_SIZE, + 4, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that is smaller than maxsize + // + Value1 =3D 0x34; + Status =3D gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS), + sizeof (Value1), + &Value1); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status =3D gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size that matches maxsize + // + Value2 =3D 0xa1b2c3d4; + Status =3D gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS), + sizeof (Value2), + &Value2); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // + Status =3D gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var of size larger than maxsize + // + Buffer =3D AllocateZeroPool (40); + UT_ASSERT_NOT_NULL (Buffer); + Status =3D gRT->SetVariable (L"MaxSizeNoLockVar", + &mTestNamespaceGuid2, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS), + 40, + Buffer); + UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status =3D=3D EF= I_INVALID_PARAMETER)); + + FreePool (Buffer); + + return UNIT_TEST_PASSED; +} // TestMaxSizeNamespaceNoLock + +UNIT_TEST_STATUS +EFIAPI +TestMustHaveAttrWildcardNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"MustHaveAttrWildcardNoLockVar###= #", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + (EFI_VARIABLE_NON_VOLATILE | EFI_= VARIABLE_BOOTSERVICE_ACCESS), + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that doesn't have the must-have attributes + // + Value =3D 0x56; + Status =3D gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar1573", + &mTestNamespaceGuid1, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (Value), + &Value); + UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status =3D=3D EF= I_INVALID_PARAMETER)); + + // + // Try to write a var that has exactly the required attributes + // + Status =3D gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar1234", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // NOTE: some implementations of VP will require the musthave attributes= to be passed even when deleting + // + Status =3D gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar1234", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Try to write a var that has the required attributes and one extra att= ribute + // + Status =3D gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar5612", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to delete the var + // NOTE: some implementations of VP will require the musthave attributes= to be passed even when deleting + // + Status =3D gRT->SetVariable (L"MustHaveAttrWildcardNoLockVar5612", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestMustHaveAttrWildcardNoLock + +UNIT_TEST_STATUS +EFIAPI +TestPolicyprioritizationNoLock ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value8; + UINT16 Value16; + UINT32 Value32; + UINT64 Value64; + + // + // Register a policy targeting the specific var + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid3, + L"PolicyPriorityTestVar123", + 8, // min size of UINT64 + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Register a policy with wildcards in the name + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid3, + L"PolicyPriorityTestVar###", + 4, // min size of UINT32 + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Register a policy with wildcards in the name + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid3, + NULL, + 2, // min size of UINT16 + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // The idea is that the most specific policy is applied: + // For varname "TestVar", the namespace-wide one should apply: UINT16 = minimum + // For varname "PolicyPriorityTestVar567" the wildcard policy should a= pply: UINT32 minimum + // For varname "PolicyPriorityTestVar123" the var-specific policy shou= ld apply: UINT64 minimum + // + + // + // Let's confirm the namespace-wide policy enforcement + // + Value8 =3D 0x78; + Status =3D gRT->SetVariable (L"TestVar", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value8), + &Value8); + UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status =3D=3D EF= I_INVALID_PARAMETER)); + + Value16 =3D 0x6543; + Status =3D gRT->SetVariable (L"TestVar", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value16), + &Value16); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's confirm the wildcard policy enforcement + // + Value16 =3D 0xabba; + Status =3D gRT->SetVariable (L"PolicyPriorityTestVar567", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value16), + &Value16); + UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status =3D=3D EF= I_INVALID_PARAMETER)); + + Value32 =3D 0xfedcba98; + Status =3D gRT->SetVariable (L"PolicyPriorityTestVar567", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value32), + &Value32); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's confirm the var-specific policy enforcement + // + Value32 =3D 0x8d3f627c; + Status =3D gRT->SetVariable (L"PolicyPriorityTestVar123", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value32), + &Value32); + UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status =3D=3D EF= I_INVALID_PARAMETER)); + + Value64 =3D 0xbebecdcdafaf6767; + Status =3D gRT->SetVariable (L"PolicyPriorityTestVar123", + &mTestNamespaceGuid3, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value64), + &Value64); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestPolicyprioritizationNoLock + +/** + LockNow Policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestExistingVarLockNow ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + // + // Write a var that we'll protect next + // + Value =3D 0x78; + Status =3D gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Register a LockNow policy targeting the var + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"ExistingLockNowVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_NOW); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Attempt to modify the locked var + // + Value =3D 0xA5; + Status =3D gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Attempt to delete the locked var + // + Status =3D gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // This variable is deleted in final cleanup. + // + + return UNIT_TEST_PASSED; +} // TestExistingVarLockNow + +UNIT_TEST_STATUS +EFIAPI +TestNonexistentVarLockNow ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + UINTN Size; + + // + // Make sure the variable we're about to create the policy for doesn't e= xist + // + Size =3D 0; + Status =3D gRT->GetVariable (L"NonexistentLockNowVar", + &mTestNamespaceGuid1, + NULL, + &Size, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); + + // + // Register a LockNow policy targeting the var + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"NonexistentLockNowVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_NOW); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Attempt to create the locked var + // + Value =3D 0xA5; + Status =3D gRT->SetVariable (L"NonexistentLockNowVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + return UNIT_TEST_PASSED; +} // TestNonexistentVarLockNow + +/** + LockOnCreate Policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestExistingVarLockOnCreate ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + // + // Write a var that we'll protect later + // + Value =3D 0x78; + Status =3D gRT->SetVariable (L"ExistingLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Register a LockNow policy targeting the var + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"ExistingLockOnCreateVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_ON_CREAT= E); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Attempt to modify the locked var + // + Value =3D 0xA5; + Status =3D gRT->SetVariable (L"ExistingLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Attempt to delete the locked var + // + Status =3D gRT->SetVariable (L"ExistingLockOnCreateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // This variable is deleted in final cleanup. + // + + return UNIT_TEST_PASSED; +} // TestExistingVarLockOnCreate + +UNIT_TEST_STATUS +EFIAPI +TestNonexistentVarLockOnCreate ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value1; + UINT32 Value2; + UINTN Size; + + // + // Make sure the variable we're about to create the policy for doesn't e= xist + // + Size =3D 0; + Status =3D gRT->GetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + NULL, + &Size, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); + + // + // Register a LockOnCreate policy targeting the var + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"NonexistentLockOnCreateVar", + 2, // min size of 2 bytes, UINT16+ + VARIABLE_POLICY_NO_MAX_SIZE, + EFI_VARIABLE_RUNTIME_ACCESS, // mu= st have RT attr + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_ON_CREAT= E); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Attempt to create the var, but smaller than min size + // + Value1 =3D 0xA5; + Status =3D gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value1), + &Value1); + UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status =3D=3D EF= I_INVALID_PARAMETER)); + + // + // Now let's make sure attribute req is enforced + // + Value2 =3D 0x43218765; + Status =3D gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value2), + &Value2); + UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status =3D=3D EF= I_INVALID_PARAMETER)); + + // + // Now let's create a valid variable + // + Value2 =3D 0x43218765; + Status =3D gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value2), + &Value2); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's make sure we can't modify it + // + Value2 =3D 0xa5a5b6b6; + Status =3D gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (Value2), + &Value2); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Finally, let's make sure we can't delete it + // + Status =3D gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // This variable is deleted in final cleanup. + // + + return UNIT_TEST_PASSED; +} // TestNonexistentVarLockOnCreate + +/** + LockOnVarState Policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestLockOnVarStateBeforeCreate ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINTN Size; + UINT8 Value; + + // + // First of all, let's make sure the var we're trying to protect doesn't= exist + // + Size =3D 0; + Status =3D gRT->GetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + NULL, + &Size, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); + + // + // Good, now let's create a policy + // + Status =3D RegisterVarStateVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"NonexistentLockOnVarStateVar"= , + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + &mTestNamespaceGuid1, + L"Trigger1", + 0x7E); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now we write the trigger var + // + Value =3D 0x7E; + Status =3D gRT->SetVariable (L"Trigger1", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Ok, now we attempt to write a var protected by the trigger + // + Value =3D 0xFA; + Status =3D gRT->SetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Let's modify the trigger var and "untrigger" the policy + // + Value =3D 0x38; + Status =3D gRT->SetVariable (L"Trigger1", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now we should be able to create the var targeted by the policy + // + Value =3D 0x23; + Status =3D gRT->SetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Cleanup: delete the trigger and the protected var + // + Status =3D gRT->SetVariable (L"Trigger1", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + Status =3D gRT->SetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestLockOnVarStateBeforeCreate + +UNIT_TEST_STATUS +EFIAPI +TestLockOnVarStateAfterCreate ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + // + // Let's create a policy + // + Status =3D RegisterVarStateVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"ExistingLockOnVarStateVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + &mTestNamespaceGuid1, + L"Trigger2", + 0x5C); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should be able to write targeted var since the policy isn't active ye= t. + // + Value =3D 0x17; + Status =3D gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's modify the var to make sure the policy isn't acting like a lock= -on-create one + // + Value =3D 0x30; + Status =3D gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now we trigger the policy + // + Value =3D 0x5C; + Status =3D gRT->SetVariable (L"Trigger2", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's now verify the variable is protected + // + Value =3D 0xB9; + Status =3D gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Ok, to clean up, we need to remove the trigger var, so delete it, and= then delete the target var + // + Status =3D gRT->SetVariable (L"Trigger2", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + Status =3D gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestLockOnVarStateAfterCreate + +UNIT_TEST_STATUS +EFIAPI +TestLockOnVarStateInvalidLargeTrigger ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT16 Value; + + // + // First let's create a variable policy + // + Status =3D RegisterVarStateVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidLargeTriggerLockOnVarS= tateVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + &mTestNamespaceGuid1, + L"Trigger3", + 0x5C); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now attempt to trigger the lock but with a variable larger than one b= yte + // + Value =3D 0x8085; + Status =3D gRT->SetVariable (L"Trigger3", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should still be able to create the targeted var + // + Value =3D 0x1234; + Status =3D gRT->SetVariable (L"InvalidLargeTriggerLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's clean up by deleting the invalid trigger and the targeted var + // + Status =3D gRT->SetVariable (L"Trigger3", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + Status =3D gRT->SetVariable (L"InvalidLargeTriggerLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestLockOnVarStateInvalidLargeTrigger + +UNIT_TEST_STATUS +EFIAPI +TestLockOnVarStateWrongValueTrigger ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8 Value; + + // + // First let's create a variable policy + // + Status =3D RegisterVarStateVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"WrongValueTriggerLockOnVarSta= teVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + &mTestNamespaceGuid1, + L"Trigger4", + 0xCA); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now attempt to trigger the lock but with a wrong value + // + Value =3D 0x80; + Status =3D gRT->SetVariable (L"Trigger4", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Should still be able to create the targeted var + // + Value =3D 0x14; + Status =3D gRT->SetVariable (L"WrongValueTriggerLockOnVarStateVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Let's clean up by deleting the invalid trigger and the targeted var + // + Status =3D gRT->SetVariable (L"Trigger4", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + Status =3D gRT->SetVariable (L"WrongValueTriggerLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestLockOnVarStateWrongValueTrigger + +/** + Invalid policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +TestInvalidAttributesPolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + // + // The only must/can't have attributes supported by VPE are NV, BS, and = RT. They are 1, 2, and 4, respectively. + // Let's try some bits higher than that? + // + + // + // Trying must have attribute 0x8 which is EFI_VARIABLE_HARDWARE_ERROR_R= ECORD + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidMustHaveAttributesPolicyV= ar1", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + EFI_VARIABLE_HARDWARE_ERROR_RECORD= , + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_HARDWARE_ERROR_RECO= RD returned %r\n", Status); + + // + // Let's try 0x10 - EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, a deprecate= d attribute + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidMustHaveAttributesPolicyV= ar2", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + EFI_VARIABLE_AUTHENTICATED_WRITE_A= CCESS, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_AUTHENTICATED_WRITE= _ACCESS returned %r\n", Status); + + // + // Let's try 0x20 - EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidMustHaveAttributesPolicyV= ar3", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + EFI_VARIABLE_TIME_BASED_AUTHENTICA= TED_WRITE_ACCESS, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_TIME_BASED_AUTHENTI= CATED_WRITE_ACCESS returned %r\n", Status); + + // + // Let's try something wild, like 0x4000 + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidMustHaveAttributesPolicyV= ar4", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + 0x4000, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting must have attr to 0x4000 returned %r\n", Status); + + // + // Now repeat the same tests, but for the can't-have param + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidCantHaveAttributesPolicyV= ar1", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + EFI_VARIABLE_HARDWARE_ERROR_RECORD= , + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_HARDWARE_ERROR_RECO= RD returned %r\n", Status); + + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidCantHaveAttributesPolicyV= ar2", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + EFI_VARIABLE_AUTHENTICATED_WRITE_A= CCESS, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_AUTHENTICATED_WRITE= _ACCESS returned %r\n", Status); + + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidCantHaveAttributesPolicyV= ar3", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + EFI_VARIABLE_TIME_BASED_AUTHENTICA= TED_WRITE_ACCESS, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_TIME_BASED_AUTHENTI= CATED_WRITE_ACCESS returned %r\n", Status); + + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidCantHaveAttributesPolicyV= ar4", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + 0x4000, + VARIABLE_POLICY_TYPE_NO_LOCK); + UT_LOG_INFO ("Setting cant have attr to 0x4000 returned %r\n", Status); + + return UNIT_TEST_PASSED; +} // TestInvalidAttributesPolicy + +UNIT_TEST_STATUS +EFIAPI +TestLargeMinSizePolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + // + // Let's set the min size to 2GB and see what happens + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"LargeMinSizeInvalidPolicyVar", + 0x80000000, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + + UT_LOG_INFO ("Setting min size to 0x80000000 returned %r\n", Status); + + return UNIT_TEST_PASSED; +} // TestLargeMinSizePolicy + +UNIT_TEST_STATUS +EFIAPI +TestZeroMaxSizePolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + // + // Let's set the max size to 0 and see what happens + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"ZeroMinSizeInvalidPolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + 0, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK); + //UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); // this fails on QC. Real b= ug? Do we care? + UT_LOG_INFO ("Setting max size to 0 returned %r\n", Status); + + return UNIT_TEST_PASSED; +} // TestZeroMaxSizePolicy + +UNIT_TEST_STATUS +EFIAPI +TestInvalidPolicyTypePolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + // + // Let's set policy type to an invalid value and see what happens + // Valid ones are: + // VARIABLE_POLICY_TYPE_NO_LOCK 0 + // VARIABLE_POLICY_TYPE_LOCK_NOW 1 + // VARIABLE_POLICY_TYPE_LOCK_ON_CREATE 2 + // VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE 3 + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidPolicyTypePolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + 4); + UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); + + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"InvalidPolicyTypePolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + 147); + UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); + + return UNIT_TEST_PASSED; +} // TestInvalidPolicyTypePolicy + +/** + Test dumping policy. +**/ +UNIT_TEST_STATUS +EFIAPI +TestDumpPolicy ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT8* Buffer; + UINT32 Size; + + // + // First let's call DumpVariablePolicy with null buffer to get size + // + Size =3D 0; + Status =3D mVarPol->DumpVariablePolicy (NULL, &Size); + UT_ASSERT_STATUS_EQUAL (Status, EFI_BUFFER_TOO_SMALL); + + // + // Now we allocate the buffer for the dump + // + Buffer =3D NULL; + Buffer =3D AllocatePool (Size); + UT_ASSERT_NOT_NULL (Buffer); + + // + // Now we get the dump. In this test we will not analyze the dump. + // + Status =3D mVarPol->DumpVariablePolicy (Buffer, &Size); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // TestDumpPolicy + +/** + Test policy version. +**/ +UNIT_TEST_STATUS +EFIAPI +TestPolicyVersion ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + VARIABLE_POLICY_ENTRY *NewEntry; + + // + // Create the new entry using a helper lib + // + NewEntry =3D NULL; + Status =3D CreateBasicVariablePolicy (&mTestNamespaceGuid1, + L"PolicyVersionTestNoLockVar", + VARIABLE_POLICY_NO_MIN_SIZE, + 4, // max size of 4 bytes + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_NO_LOCK, + &NewEntry); + UT_ASSERT_NOT_EFI_ERROR (Status); + + NewEntry->Version =3D 0x1234; + Status =3D mVarPol->RegisterVariablePolicy (NewEntry); + UT_LOG_INFO ("Registering policy entry with an unknown version status: %= r\n", Status); + + FreePool (NewEntry); + + return UNIT_TEST_PASSED; +} // TestPolicyVersion + +/** + Lock Policy Tests. +**/ +UNIT_TEST_STATUS +EFIAPI +LockPolicyEngineTests ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + UINT16 Value; + UINT64 Value64; + BOOLEAN State; + + // + // First let's register a policy that we'll test after VPE lock + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"BeforeVpeLockNoLockPolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + 4, // max size of 4 bytes + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_ON_CREAT= E); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now, lock VPE! + // + Status =3D mVarPol->LockVariablePolicy (); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // See if we can lock it again? + // + Status =3D mVarPol->LockVariablePolicy (); + UT_LOG_INFO ("Locking VPE for second time returned %r\n", Status); + + // + // Let's confirm one of the policies from prior test suites is still enf= orced + // Attempt to delete a locked var + // + Status =3D gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // We'll make sure the policy from earlier in this test case is actively= filtering out by size + // + Value64 =3D 0x3829fed212345678; + Status =3D gRT->SetVariable (L"BeforeVpeLockNoLockPolicyVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS), + sizeof (Value64), + &Value64); + UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status =3D=3D EF= I_INVALID_PARAMETER)); + + // + // Let's create the variable from the policy now + // + Value =3D 0x323f; + Status =3D gRT->SetVariable (L"BeforeVpeLockNoLockPolicyVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Now confirm that the var is locked after creation + // + Value =3D 0x1212; + Status =3D gRT->SetVariable (L"BeforeVpeLockNoLockPolicyVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BO= OTSERVICE_ACCESS), + sizeof (Value), + &Value); + UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED); + + // + // Let's attempt to register a new policy, it should fail + // + Status =3D RegisterBasicVariablePolicy (mVarPol, + &mTestNamespaceGuid1, + L"AfterVpeLockNowPolicyVar", + VARIABLE_POLICY_NO_MIN_SIZE, + VARIABLE_POLICY_NO_MAX_SIZE, + VARIABLE_POLICY_NO_MUST_ATTR, + VARIABLE_POLICY_NO_CANT_ATTR, + VARIABLE_POLICY_TYPE_LOCK_NOW); + UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); + + // + // Make sure VPE is enabled + // + Status =3D mVarPol->IsVariablePolicyEnabled (&State); + UT_ASSERT_NOT_EFI_ERROR (Status); + UT_ASSERT_EQUAL (State, TRUE); + + // + // Finally, make sure we can't disable VPE + // + Status =3D mVarPol->DisableVariablePolicy (); + UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); + + return UNIT_TEST_PASSED; +} // LockPolicyEngineTests + +/** + Save context and reboot after the lock policy test suite. +**/ +STATIC +VOID +EFIAPI +SaveContextAndReboot ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + // + // Now, save all the data associated with this framework. + // TODO: Need to add to the UnitTestFrameworkPkg + Status =3D SaveFrameworkState( GetActiveFrameworkHandle(), NULL, 0 ); + + // + // If we're all good, let's book... + if (!EFI_ERROR( Status )) + { + // + // Next, we want to update the BootNext variable to USB + // so that we have a fighting chance of coming back here. + // + // TODO: Need to add to the UnitTestFrameworkPkg + // SetBootNextDevice(); + + // + // Reset + DEBUG(( DEBUG_INFO, "%a - Rebooting! Launch this test again once boote= d.\n", __FUNCTION__ )); + gRT->ResetSystem( EfiResetCold, EFI_SUCCESS, 0, NULL ); + DEBUG(( DEBUG_ERROR, "%a - Unit test failed to quit! Framework can no = longer be used!\n", __FUNCTION__ )); + + // + // We REALLY shouldn't be here. + Status =3D EFI_ABORTED; + } + + return; +} // SaveContextAndReboot + +/** + Disable policy tests. +**/ +UNIT_TEST_STATUS +EFIAPI +DisablePolicyEngineTests ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + BOOLEAN State; + UINT8 Value; + + // + // First, we disable the variable policy + // + Status =3D mVarPol->DisableVariablePolicy (); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Confirm it's disabled + // + Status =3D mVarPol->IsVariablePolicyEnabled (&State); + UT_ASSERT_NOT_EFI_ERROR (Status); + UT_ASSERT_EQUAL (State, FALSE); + + // + // Try locking it? + // + Status =3D mVarPol->LockVariablePolicy (); + UT_LOG_INFO ("Locking VP after disabling it status: %r\n", Status); + + // + // Try modifying the var from TestExistingVarLockNow + // + Value =3D 0xB5; + Status =3D gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIAB= LE_NON_VOLATILE), + sizeof (Value), + &Value); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} // DisablePolicyEngineTests + +/** + Final Cleanup: delete some variables earlier test cases created. +**/ +STATIC +VOID +EFIAPI +FinalCleanup ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + Status =3D gRT->SetVariable (L"ExistingLockNowVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete ExistingLockNowVar status: %r\n", Status); + + Status =3D gRT->SetVariable (L"ExistingLockOnCreateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete ExistingLockOnCreateVar status: %r\n", Status); + + Status =3D gRT->SetVariable (L"NonexistentLockOnCreateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete NonexistentLockOnCreateVar status: %r\n", Status); + + Status =3D gRT->SetVariable (L"NonexistentLockNowVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete NonexistentLockNowVar status: %r\n", Status); + + Status =3D gRT->SetVariable (L"CantHaveAttrNoLockVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete CantHaveAttrNoLockVar status: %r\n", Status); + + Status =3D gRT->SetVariable (L"NonexistentLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete NonexistentLockOnVarStateVar status: %r\n", Status)= ; + + Status =3D gRT->SetVariable (L"ExistingLockOnVarStateVar", + &mTestNamespaceGuid1, + 0, + 0, + NULL); + UT_LOG_INFO ("Delete ExistingLockOnVarStateVar status: %r\n", Status); +} // FinalCleanup + +/** + + Main fuction sets up the unit test environment. + +**/ +EFI_STATUS +EFIAPI +UefiMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE* SystemTable) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE GettingStartedTestSuite; + UNIT_TEST_SUITE_HANDLE NoLockPoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE LockNowPoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE LockOnCreatePoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE LockOnVarStatePoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE InvalidPoliciesTestSuite; + UNIT_TEST_SUITE_HANDLE DumpPolicyTestSuite; + UNIT_TEST_SUITE_HANDLE PolicyVersionTestSuite; + UNIT_TEST_SUITE_HANDLE LockPolicyTestSuite; + UNIT_TEST_SUITE_HANDLE DisablePolicyTestSuite; + + Framework =3D NULL; + GettingStartedTestSuite =3D NULL; + NoLockPoliciesTestSuite =3D NULL; + LockNowPoliciesTestSuite =3D NULL; + LockOnCreatePoliciesTestSuite =3D NULL; + LockOnVarStatePoliciesTestSuite =3D NULL; + InvalidPoliciesTestSuite =3D NULL; + DumpPolicyTestSuite =3D NULL; + PolicyVersionTestSuite =3D NULL; + LockPolicyTestSuite =3D NULL; + DisablePolicyTestSuite =3D NULL; + + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSIO= N)); + + // + // Start setting up the test framework for running the tests. + // + Status =3D InitUnitTestFramework (&Framework, UNIT_TEST_APP_NAME, gEfiCa= llerBaseName, UNIT_TEST_APP_VERSION); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status =3D %r\n= ", Status)); + goto EXIT; + } + + // + // Test suite 1: Getting Started. Get VP protocol, check state, log revi= sion + // + Status =3D CreateUnitTestSuite (&GettingStartedTestSuite, Framework, "Ge= tting Started", "Common.VP.GettingStarted", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Getting St= arted Test Suite\n")); + Status =3D EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (GettingStartedTestSuite, "Confirm VP is enabled", "Common.V= P.GettingStarted.CheckVpEnabled", CheckVpEnabled, LocateVarPolicyPreReq, NU= LL, NULL); + AddTestCase (GettingStartedTestSuite, "Check VP revision", "Common.VP.Ge= ttingStarted.CheckVpRevision", CheckVpRevision, LocateVarPolicyPreReq, NULL= , NULL); + + // + // Test suite 2: Test NoLock Policies + // + Status =3D CreateUnitTestSuite (&NoLockPoliciesTestSuite, Framework, "Ex= ercise NoLock Policies", "Common.VP.NoLockPolicies", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the NoLock Pol= icies Test Suite\n")); + Status =3D EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (NoLockPoliciesTestSuite, "Test Min Size enforcement in NoLo= ck policy", "Common.VP.NoLockPolicies.TestMinSizeNoLock", TestMinSizeNoLock= , LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test Max Size enforcement in NoLo= ck policy", "Common.VP.NoLockPolicies.TestMaxSizeNoLock", TestMaxSizeNoLock= , LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test Must Have Attribute enforcem= ent in NoLock policy", "Common.VP.NoLockPolicies.TestMustHaveAttrNoLock", T= estMustHaveAttrNoLock, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test Can't Have Attribute enforce= ment in NoLock policy", "Common.VP.NoLockPolicies.TestCantHaveAttrNoLock", = TestCantHaveAttrNoLock, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test Max Size enforcement in NoLo= ck policy for entire namespace", "Common.VP.NoLockPolicies.TestMaxSizeNames= paceNoLock", TestMaxSizeNamespaceNoLock, LocateVarPolicyPreReq, NULL, NULL)= ; + AddTestCase (NoLockPoliciesTestSuite, "Test Must Have Attribute enforcem= ent in NoLock policy with wildcards", "Common.VP.NoLockPolicies.TestMustHav= eAttrWildcardNoLock", TestMustHaveAttrWildcardNoLock, LocateVarPolicyPreReq= , NULL, NULL); + AddTestCase (NoLockPoliciesTestSuite, "Test policy prioritization betwee= n namespace-wide, wildcard, and var-specific policies", "Common.VP.NoLockPo= licies.TestPolicyprioritizationNoLock", TestPolicyprioritizationNoLock, Loc= ateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 3: Test LockNow policies + // + Status =3D CreateUnitTestSuite (&LockNowPoliciesTestSuite, Framework, "E= xercise LockNow Policies", "Common.VP.LockNowPolicies", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the LockNow Po= licies Test Suite\n")); + Status =3D EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (LockNowPoliciesTestSuite, "Test LockNow policy for a pre-ex= isting variable", "Common.VP.LockNowPolicies.TestExistingVarLockNow", TestE= xistingVarLockNow, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (LockNowPoliciesTestSuite, "Test LockNow policy for a nonexi= stent variable", "Common.VP.LockNowPolicies.TestNonexistentVarLockNow", Tes= tNonexistentVarLockNow, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 4: Test LockOnCreate policies + // + Status =3D CreateUnitTestSuite (&LockOnCreatePoliciesTestSuite, Framewor= k, "Exercise LockOnCreate Policies", "Common.VP.LockOnCreate", NULL, NULL); + if (EFI_ERROR (Status)) + { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the LockOnCrea= te Policies Test Suite\n")); + Status =3D EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (LockOnCreatePoliciesTestSuite, "Test LockOnCreate policy fo= r a pre-existing variable", "Common.VP.LockOnCreate.TestExistingVarLockOnCr= eate", TestExistingVarLockOnCreate, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (LockOnCreatePoliciesTestSuite, "Test LockOnCreate policy fo= r a nonexistent variable", "Common.VP.LockOnCreate.TestNonexistentVarLockOn= Create", TestNonexistentVarLockOnCreate, LocateVarPolicyPreReq, NULL, NULL)= ; + + // + // Test suite 5: Test LockOnVarState policies + // + Status =3D CreateUnitTestSuite (&LockOnVarStatePoliciesTestSuite, Framew= ork, "Exercise LockOnVarState Policies", "Common.VP.LockOnVarState", NULL, = NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the LockOnVarS= tate Policies Test Suite\n")); + Status =3D EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState polic= y for a nonexistent variable", "Common.VP.LockOnVarState.TestLockOnVarState= BeforeCreate", TestLockOnVarStateBeforeCreate, LocateVarPolicyPreReq, NULL,= NULL); + AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState polic= y for a pre-existing variable", "Common.VP.LockOnVarState.TestLockOnVarStat= eAfterCreate", TestLockOnVarStateAfterCreate, LocateVarPolicyPreReq, NULL, = NULL); + AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState polic= y triggered by invalid-size variable", "Common.VP.LockOnVarState.TestLockOn= VarStateInvalidLargeTrigger", TestLockOnVarStateInvalidLargeTrigger, Locate= VarPolicyPreReq, NULL, NULL); + AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOnVarState polic= y triggered by invalid-value variable", "Common.VP.LockOnVarState.TestLockO= nVarStateWrongValueTrigger", TestLockOnVarStateWrongValueTrigger, LocateVar= PolicyPreReq, NULL, NULL); + + // + // Test suite 6: Test registering invalid policies + // + Status =3D CreateUnitTestSuite (&InvalidPoliciesTestSuite, Framework, "A= ttempt registering invalid policies", "Common.VP.InvalidPolicies", NULL, NU= LL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Invalid Po= licies Test Suite\n")); + Status =3D EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid must-ha= ve attributes", "Common.VP.InvalidPolicies.TestInvalidAttributesPolicy", Te= stInvalidAttributesPolicy, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid attribu= tes", "Common.VP.InvalidPolicies.TestLargeMinSizePolicy", TestLargeMinSizeP= olicy, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid attribu= tes", "Common.VP.InvalidPolicies.TestZeroMaxSizePolicy", TestZeroMaxSizePol= icy, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (InvalidPoliciesTestSuite, "Test policy with invalid type", = "Common.VP.InvalidPolicies.TestInvalidPolicyTypePolicy", TestInvalidPolicyT= ypePolicy, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 7: Test dumping the policy + // + Status =3D CreateUnitTestSuite (&DumpPolicyTestSuite, Framework, "Attemp= t dumping policy", "Common.VP.DumpPolicy", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Dump Polic= y Test Suite\n")); + Status =3D EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (DumpPolicyTestSuite, "Test dumping policy", "Common.VP.Dump= Policy.TestDumpPolicy", TestDumpPolicy, LocateVarPolicyPreReq, NULL, NULL); + + // + // Test suite 8: Test policy version + // + Status =3D CreateUnitTestSuite (&PolicyVersionTestSuite, Framework, "Use= non-zero policy version", "Common.VP.PolicyVersion", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Policy Ver= sion Test Suite\n")); + Status =3D EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (PolicyVersionTestSuite, "Test policy version", "Common.VP.D= umpPolicy.TestPolicyVersion", TestPolicyVersion, LocateVarPolicyPreReq, NUL= L, NULL); + + // + // Test suite 9: Lock VPE and test implications + // + Status =3D CreateUnitTestSuite (&LockPolicyTestSuite, Framework, "Lock p= olicy, test it", "Common.VP.LockPolicyTests", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Lock Polic= y Test Suite\n")); + Status =3D EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (LockPolicyTestSuite, "Test locking policy", "Common.VP.Lock= PolicyTests.LockPolicyEngineTests", LockPolicyEngineTests, LocateVarPolicyP= reReq, NULL, NULL); + AddTestCase (LockPolicyTestSuite, "Test locking policy", "Common.VP.Lock= PolicyTests.LockPolicyEngineTests", LockPolicyEngineTests, LocateVarPolicyP= reReq, SaveContextAndReboot, NULL); + + // + // Test suite 10: Disable var policy and confirm expected behavior + // + Status =3D CreateUnitTestSuite (&DisablePolicyTestSuite, Framework, "Dis= able policy, test it", "Common.VP.DisablePolicyTests", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for the Disable Po= licy Test Suite\n")); + Status =3D EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase (DisablePolicyTestSuite, "Confirm VP is enabled", "Common.VP= .DisablePolicyTests.CheckVpEnabled", CheckVpEnabled, LocateVarPolicyPreReq,= NULL, NULL); + AddTestCase (DisablePolicyTestSuite, "Test LockNow policy for a pre-exis= ting variable", "Common.VP.DisablePolicyTests.TestExistingVarLockNow", Test= ExistingVarLockNow, LocateVarPolicyPreReq, NULL, NULL); + AddTestCase (DisablePolicyTestSuite, "Test disabling policy", "Common.VP= .DisablePolicyTests.DisablePolicyEngineTests", DisablePolicyEngineTests, Lo= cateVarPolicyPreReq, FinalCleanup, NULL); + + // + // Execute the tests. + // + Status =3D RunAllTestSuites (Framework); + +EXIT: + if (Framework !=3D NULL) { + FreeUnitTestFramework (Framework); + } + + return Status; +} // UefiMain diff --git a/MdeModulePkg/MdeModulePkg.ci.yaml b/MdeModulePkg/MdeModulePkg.= ci.yaml index 1cfc1328390e..88a192d0e2a8 100644 --- a/MdeModulePkg/MdeModulePkg.ci.yaml +++ b/MdeModulePkg/MdeModulePkg.ci.yaml @@ -35,7 +35,9 @@ "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec" ], # For UEFI shell based apps - "AcceptableDependencies-UEFI_APPLICATION":[], + "AcceptableDependencies-UEFI_APPLICATION":[ + "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec" + ], "IgnoreInf": [] }, diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index f0a75a3b337b..414a6c62dfdb 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -19,6 +19,8 @@ [Defines] BUILD_TARGETS =3D DEBUG|RELEASE|NOOPT SKUID_IDENTIFIER =3D DEFAULT +!include UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc + [LibraryClasses] # # Entry point @@ -314,6 +316,10 @@ [Components] MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf + MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFunc= TestApp.inf { + + UnitTestBootLib|UnitTestFrameworkPkg/Library/UnitTestBootLibNull/Uni= tTestBootLibNull.inf + } MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.m= d b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md new file mode 100644 index 000000000000..804ad4173a5f --- /dev/null +++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md @@ -0,0 +1,55 @@ +# variable Policy Unit Tests + +## 🔹 Copyright +Copyright (C) Microsoft Corporation. All rights reserved. +SPDX-License-Identifier: BSD-2-Clause-Patent + +## About This Test +This test verifies functionality of the Variable Policy Protocol by regist= ering various variable policies and exercising them, as well as tests locki= ng the policy, disabling it, and dumping the policy entries. + +Only policies that are created as a part of this test will be tested. +1. Try getting test context, if empty then get VP protocol, confirm that V= P is not disabled by calling IsVariablePolicyEnabled. Log VP revision. +2. "No lock" policies: + * check minsize enforcement + * check maxsize enforcement + * check musthave attr enforcement + * check canthave attr enforcement + * check one of the above with empty string policy i.e. name wildcard + * check another one of the above with a "#" containing policy string + * check policy prioritization by having a namespace-wide policy, a pol= icy with a # wildcard, and a one-var specific policy and testing which one = is enforced +3. "Lock now" policies (means if the var doesn't exist, it won't be create= d; if one exists, it can't be updated): + * test a policy for an already existing variable, verify we can't writ= e into that variable + * create a policy for a non-existing variable and attempt to register = such var +4. "Lock on create" policies (means the var can still be created, but no u= pdates later, existing vars can't be updated): + * create a var, lock it with LockOnCreate, attempt to update its conte= nts + * create LockOnCreate VP, attempt to create var with invalid size, the= n invalid attr, then create valid var, attempt to update its contents +5. "Lock on var state" policies (means the var protected by this policy ca= n't be created or updated once the trigger is set) + * create VP, trigger lock with a valid var, attempt to create a locked= var, then modify the trigger var, create locked var + * create VP, create targeted var, modify it, trigger lock, attempt to = modify var + * create VP, trigger lock with invalid (larger than one byte) var, see= if VPE allows creation of the locked var (it should allow) + * create VP, set locking var with wrong value, see if VPE allows creat= ion of the locked var (should allow) +6. Attempt registering invalid policy entries + * invalid required and banned attributes + * large min size - let's say 2GB + * max size equal to 0 + * invalid policy type +7. Exercise dumping policy. No need to check the validity of the dump blob= . +8. Test registering a policy with a random version. +9. Lock VPE, make sure old policies are enforced, new ones can't be regist= ered. + * Register a LockOnCreate policy + * Lock VPE + * Test locking it again. + * Verify one of the prior policies is enforced + * Make sure we can create variables even if those are protected by Loc= kOnCreate policy, after locking the VPE + * Attempt to register new policies + * Make sure can't disable VPE + * Cleanup: save context and reboot +10. Disable variable policy and try some things + * Locate Variable Policy Protocol + * Make sure VP is enabled + * Register a policy + * Disable VPE + * Call IsVariablePolicyEnabled to confirm it's disabled. + * Make sure can't lock policy + * Make sure the policy from a is no longer enforced + * Final cleanup: delete vars that were created in some earlier test su= ites diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Variable= PolicyFuncTestApp.inf b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestA= pp/VariablePolicyFuncTestApp.inf new file mode 100644 index 000000000000..9ad277a547c2 --- /dev/null +++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyF= uncTestApp.inf @@ -0,0 +1,42 @@ +## @file +# Uefi Shell based Application that unit tests the Variable Policy Protoco= l +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D VariablePolicyFuncTestApp + FILE_GUID =3D B653C4C3-3FCC-4B6C-8051-5F692AEAECBA + MODULE_TYPE =3D UEFI_APPLICATION + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D UefiMain + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D X64 AARCH64 +# + +[Sources] + VariablePolicyFuncTestApp.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + BaseLib + UnitTestLib + UnitTestBootLib + PrintLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + MemoryAllocationLib + VariablePolicyHelperLib + +[Protocols] + gEdkiiVariablePolicyProtocolGuid -- 2.26.2.windows.1.8.g01c50adf56.20200515075929 -=3D-=3D-=3D-=3D-=3D-=3D Groups.io Links: You receive all messages sent to this group. View/Reply Online (#60650): https://nam06.safelinks.protection.outlook.com/= ?url=3Dhttps%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F60650&data= =3D02%7C01%7Cbret.barkelew%40microsoft.com%7C48059bf775454b7b4d2608d807a3e3= 08%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637267747768910602&sdat= a=3DlgY1iwLZRvqFnPCm3Zmox4LalLdnrkxq8r155yNFbR4%3D&reserved=3D0 Mute This Topic: https://nam06.safelinks.protection.outlook.com/?url=3Dhttp= s%3A%2F%2Fgroups.io%2Fmt%2F74646439%2F1852292&data=3D02%7C01%7Cbret.bar= kelew%40microsoft.com%7C48059bf775454b7b4d2608d807a3e308%7C72f988bf86f141af= 91ab2d7cd011db47%7C1%7C0%7C637267747768910602&sdata=3DCKFvSs5%2BCDn0Kaq= %2F0MDLQMlQ79HkviHQNBZde8tM5Ro%3D&reserved=3D0 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://nam06.safelinks.protection.outlook.com/?url=3Dhttps%3A= %2F%2Fedk2.groups.io%2Fg%2Fdevel%2Funsub&data=3D02%7C01%7Cbret.barkelew= %40microsoft.com%7C48059bf775454b7b4d2608d807a3e308%7C72f988bf86f141af91ab2= d7cd011db47%7C1%7C0%7C637267747768910602&sdata=3DHrb%2BQ%2FgFRUJ8%2F%2F= D6bMbsaySdS0qu4aC5Iy2dMryQyrw%3D&reserved=3D0 [bret.barkelew@microsoft= .com] -=3D-=3D-=3D-=3D-=3D-=3D --_000_CY4PR21MB07431BB6A62B00E160B57138EF9A0CY4PR21MB0743namp_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable
Bump. This specif= ic patch needs Reviews.

- Bret


From: devel@edk2.groups.io = <devel@edk2.groups.io> on behalf of Bret Barkelew via groups.io <b= ret=3Dcorthon.com@groups.io>
Sent: Tuesday, June 2, 2020 11:58 PM
To: devel@edk2.groups.io <devel@edk2.groups.io>
Cc: Jian J Wang <jian.j.wang@intel.com>; Hao A Wu <hao.a.wu= @intel.com>; liming.gao <liming.gao@intel.com>
Subject: [EXTERNAL] [edk2-devel] [PATCH v5 14/14] MdeModulePkg: Add = a shell-based functional test for VariablePolicy
 
https://nam06.safelinks.protection.outlook.com/?url=3Dh= ttps%3A%2F%2Fbugzilla.tianocore.org%2Fshow_bug.cgi%3Fid%3D2522&amp;data= =3D02%7C01%7Cbret.barkelew%40microsoft.com%7C48059bf775454b7b4d2608d807a3e3= 08%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637267747768910602&amp;= sdata=3D7sdOwPRBe3bmI19WebIFlV5EgEF0z%2FkNunFwPnAhXj4%3D&amp;reserved= =3D0

To verify that VariablePolicy is correctly integrated
on platforms, add a Shell-based functional test to
confirm expected behavior.

NOTE: This test assumes that VariablePolicy is built
with PcdAllowVariablePolicyEnforcementDisable set to
TRUE.

Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Bret Barkelew <brbarkel@microsoft.com>
Signed-off-by: Bret Barkelew <brbarkel@microsoft.com>
---
 MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyF= uncTestApp.c   | 1978 ++++++++= 3;+++++++++++
 MdeModulePkg/MdeModulePkg.ci.yaml      =             &nb= sp;            =             &nb= sp;       |    4 +-
 MdeModulePkg/MdeModulePkg.dsc      &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;          |  &n= bsp; 6 +
 MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md =             &nb= sp;       |   55 +
 MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyF= uncTestApp.inf |   42 +
 5 files changed, 2084 insertions(+), 1 deletion(-)

diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Variable= PolicyFuncTestApp.c b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp= /VariablePolicyFuncTestApp.c
new file mode 100644
index 000000000000..e41b6e7a43d5
--- /dev/null
+++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Var= iablePolicyFuncTestApp.c
@@ -0,0 +1,1978 @@
+/** @file

+UEFI Shell based application for unit testing the Variable Policy Prot= ocol.

+

+Copyright (c) Microsoft Corporation.

+SPDX-License-Identifier: BSD-2-Clause-Patent

+**/

+

+#include <Uefi.h>

+#include <Library/UefiLib.h>

+#include <Library/PrintLib.h>

+#include <Library/DebugLib.h>

+#include <Library/MemoryAllocationLib.h>

+#include <Library/UnitTestLib.h>

+#include <Library/UefiBootServicesTableLib.h>

+#include <Protocol/VariablePolicy.h>

+#include <Library/VariablePolicyHelperLib.h>

+#include <Library/UefiRuntimeServicesTableLib.h>

+#include <Library/MemoryAllocationLib.h>

+

+// TODO: Need to add to the UnitTestFrameworkPkg

+// #include <Library/UnitTestBootLib.h>

+

+#define UNIT_TEST_APP_NAME        &= quot;Variable Policy Unit Test Application"

+#define UNIT_TEST_APP_VERSION     "0.1"<= br>
+

+// TODO: Need to add to the UnitTestFrameworkPkg

+UNIT_TEST_FRAMEWORK_HANDLE

+GetActiveFrameworkHandle (

+  VOID

+  );

+

+EDKII_VARIABLE_POLICY_PROTOCOL  *mVarPol =3D NULL;

+

+

+EFI_GUID mTestNamespaceGuid1 =3D { 0x3b389299, 0xabaf, 0x433b, { 0xa4,= 0xa9, 0x23, 0xc8, 0x44, 0x02, 0xfc, 0xad } };

+EFI_GUID mTestNamespaceGuid2 =3D { 0x4c49a3aa, 0xbcb0, 0x544c, { 0xb5,= 0xba, 0x34, 0xd9, 0x55, 0x13, 0x0d, 0xbe } };

+EFI_GUID mTestNamespaceGuid3 =3D { 0x5d5ab4bb, 0xcdc1, 0x655d, { 0xc6,= 0xcb, 0x45, 0xea, 0x66, 0x24, 0x1e, 0xcf } };

+

+/**

+  Prerequisite for most test cases.

+**/

+UNIT_TEST_STATUS

+EFIAPI

+LocateVarPolicyPreReq (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+

+  if (mVarPol =3D=3D NULL) {

+    Status =3D gBS->LocateProtocol (&gEdkiiVaria= blePolicyProtocolGuid,

+           &nbs= p;            &= nbsp;         NULL,

+           &nbs= p;            &= nbsp;         (VOID **) &mVarPo= l);

+    UT_ASSERT_NOT_EFI_ERROR (Status);

+    UT_ASSERT_NOT_NULL (mVarPol);

+  }

+

+  return UNIT_TEST_PASSED;

+

+} // LocateVarPolicyPreReq

+

+/**

+  Getting Started tests.

+**/

+UNIT_TEST_STATUS

+EFIAPI

+CheckVpEnabled (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  BOOLEAN State;

+

+  Status =3D mVarPol->IsVariablePolicyEnabled (&State);
+

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+  UT_ASSERT_EQUAL (State, TRUE);

+

+  return UNIT_TEST_PASSED;

+} // CheckVpEnabled

+

+UNIT_TEST_STATUS

+EFIAPI

+CheckVpRevision (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  UT_ASSERT_NOT_EQUAL (mVarPol->Revision, 0);

+  UT_LOG_INFO ("VP Revision: 0x%x\n", mVarPol->Revis= ion);

+

+  return UNIT_TEST_PASSED;

+} // CheckVpRevision

+

+/**

+  NoLock Policy tests.

+**/

+UNIT_TEST_STATUS

+EFIAPI

+TestMinSizeNoLock (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT8      Value1;

+  UINT32     Value2;

+  UINT8     *Buffer;

+

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"MinSizeNoLockVar",

+           &nbs= p;            &= nbsp;           &nbs= p;   4,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Try to write a var that is smaller than minsize

+  //

+  Value1 =3D 0x12;

+  Status =3D gRT->SetVariable (L"MinSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS),

+           &nbs= p;            &= nbsp;    sizeof (Value1),

+           &nbs= p;            &= nbsp;    &Value1);

+  UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status = =3D=3D EFI_INVALID_PARAMETER));

+

+  //

+  // Try to write a var of size that matches minsize

+  //

+  Value2 =3D 0xa1b2c3d4;

+  Status =3D gRT->SetVariable (L"MinSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS),

+           &nbs= p;            &= nbsp;    sizeof (Value2),

+           &nbs= p;            &= nbsp;    &Value2);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Should be able to delete the var

+  //

+  Status =3D gRT->SetVariable (L"MinSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Try to write a var of size larger than minsize

+  //

+  Buffer =3D AllocateZeroPool (40);

+  UT_ASSERT_NOT_NULL (Buffer);

+  Status =3D gRT->SetVariable (L"MinSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS),

+           &nbs= p;            &= nbsp;    40,

+           &nbs= p;            &= nbsp;    Buffer);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Delete the variable

+  //

+  Status =3D gRT->SetVariable (L"MinSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  FreePool (Buffer);

+

+  return UNIT_TEST_PASSED;

+} // TestMinSizeNoLock

+

+UNIT_TEST_STATUS

+EFIAPI

+TestMaxSizeNoLock (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT8      Value1;

+  UINT32     Value2;

+  UINT8     *Buffer;

+

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"MaxSizeNoLockVar",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   4,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Try to write a var that is smaller than maxsize

+  //

+  Value1 =3D 0x34;

+  Status =3D gRT->SetVariable (L"MaxSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS),

+           &nbs= p;            &= nbsp;    sizeof (Value1),

+           &nbs= p;            &= nbsp;    &Value1);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Should be able to delete the var

+  //

+  Status =3D gRT->SetVariable (L"MaxSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Try to write a var of size that matches maxsize

+  //

+  Value2 =3D 0xa1b2c3d4;

+  Status =3D gRT->SetVariable (L"MaxSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS),

+           &nbs= p;            &= nbsp;    sizeof (Value2),

+           &nbs= p;            &= nbsp;    &Value2);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Should be able to delete the var

+  //

+  Status =3D gRT->SetVariable (L"MaxSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Try to write a var of size larger than maxsize

+  //

+  Buffer =3D AllocateZeroPool (40);

+  UT_ASSERT_NOT_NULL (Buffer);

+  Status =3D gRT->SetVariable (L"MaxSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS),

+           &nbs= p;            &= nbsp;    40,

+           &nbs= p;            &= nbsp;    Buffer);

+  UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status = =3D=3D EFI_INVALID_PARAMETER));

+

+  FreePool (Buffer);

+

+  return UNIT_TEST_PASSED;

+} // TestMaxSizeNoLock

+

+UNIT_TEST_STATUS

+EFIAPI

+TestMustHaveAttrNoLock (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT8      Value;

+

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"MustHaveAttrNoLockVar",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_= ACCESS),

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Try to write a var that doesn't have the must-have attribute= s

+  //

+  Value =3D 0x56;

+  Status =3D gRT->SetVariable (L"MustHaveAttrNoLockVar&qu= ot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    EFI_VARIABLE_BOOTSERVICE_ACCESS,

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status = =3D=3D EFI_INVALID_PARAMETER));

+

+  //

+  // Try to write a var that has exactly the required attributes<= br>
+  //

+  Status =3D gRT->SetVariable (L"MustHaveAttrNoLockVar&qu= ot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Should be able to delete the var

+  // NOTE: some implementations of VP will require the musthave a= ttributes to be passed even when deleting

+  //

+  Status =3D gRT->SetVariable (L"MustHaveAttrNoLockVar&qu= ot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Try to write a var that has the required attributes and one = extra attribute

+  //

+  Status =3D gRT->SetVariable (L"MustHaveAttrNoLockVar&qu= ot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Should be able to delete the var

+  // NOTE: some implementations of VP will require the musthave a= ttributes to be passed even when deleting

+  //

+  Status =3D gRT->SetVariable (L"MustHaveAttrNoLockVar&qu= ot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+  return UNIT_TEST_PASSED;

+} // TestMustHaveAttrNoLock

+

+UNIT_TEST_STATUS

+EFIAPI

+TestCantHaveAttrNoLock (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT8      Value;

+

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"CantHaveAttrNoLockVar",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   EFI_VARIABLE_NON_VOLATILE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Try to write a var that has a can't have attr

+  //

+  Value =3D 0x78;

+  Status =3D gRT->SetVariable (L"CantHaveAttrNoLockVar&qu= ot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status = =3D=3D EFI_INVALID_PARAMETER));

+

+  //

+  // Try to write a var that satisfies the can't have requirement=

+  //

+  Status =3D gRT->SetVariable (L"CantHaveAttrNoLockVar&qu= ot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    EFI_VARIABLE_BOOTSERVICE_ACCESS,

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Should be able to delete the var

+  //

+  Status =3D gRT->SetVariable (L"CantHaveAttrNoLockVar&qu= ot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  return UNIT_TEST_PASSED;

+} // TestCantHaveAttrNoLock

+

+UNIT_TEST_STATUS

+EFIAPI

+TestMaxSizeNamespaceNoLock (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT8      Value1;

+  UINT32     Value2;

+  UINT8     *Buffer;

+

+  //

+  // Register a namespace-wide policy limiting max size to 4 byte= s

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid2,

+           &nbs= p;            &= nbsp;           &nbs= p;   NULL,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   4,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Try to write a var that is smaller than maxsize

+  //

+  Value1 =3D 0x34;

+  Status =3D gRT->SetVariable (L"MaxSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid2,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS),

+           &nbs= p;            &= nbsp;    sizeof (Value1),

+           &nbs= p;            &= nbsp;    &Value1);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Should be able to delete the var

+  //

+  Status =3D gRT->SetVariable (L"MaxSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid2,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Try to write a var of size that matches maxsize

+  //

+  Value2 =3D 0xa1b2c3d4;

+  Status =3D gRT->SetVariable (L"MaxSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid2,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS),

+           &nbs= p;            &= nbsp;    sizeof (Value2),

+           &nbs= p;            &= nbsp;    &Value2);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Should be able to delete the var

+  //

+  Status =3D gRT->SetVariable (L"MaxSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid2,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Try to write a var of size larger than maxsize

+  //

+  Buffer =3D AllocateZeroPool (40);

+  UT_ASSERT_NOT_NULL (Buffer);

+  Status =3D gRT->SetVariable (L"MaxSizeNoLockVar",<= br>
+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid2,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS),

+           &nbs= p;            &= nbsp;    40,

+           &nbs= p;            &= nbsp;    Buffer);

+  UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status = =3D=3D EFI_INVALID_PARAMETER));

+

+  FreePool (Buffer);

+

+  return UNIT_TEST_PASSED;

+} // TestMaxSizeNamespaceNoLock

+

+UNIT_TEST_STATUS

+EFIAPI

+TestMustHaveAttrWildcardNoLock (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT8      Value;

+

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"MustHaveAttrWildcardNoLockVar####",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOOTSERVICE_= ACCESS),

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Try to write a var that doesn't have the must-have attribute= s

+  //

+  Value =3D 0x56;

+  Status =3D gRT->SetVariable (L"MustHaveAttrWildcardNoLo= ckVar1573",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    EFI_VARIABLE_BOOTSERVICE_ACCESS,

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status = =3D=3D EFI_INVALID_PARAMETER));

+

+  //

+  // Try to write a var that has exactly the required attributes<= br>
+  //

+  Status =3D gRT->SetVariable (L"MustHaveAttrWildcardNoLo= ckVar1234",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Should be able to delete the var

+  // NOTE: some implementations of VP will require the musthave a= ttributes to be passed even when deleting

+  //

+  Status =3D gRT->SetVariable (L"MustHaveAttrWildcardNoLo= ckVar1234",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Try to write a var that has the required attributes and one = extra attribute

+  //

+  Status =3D gRT->SetVariable (L"MustHaveAttrWildcardNoLo= ckVar5612",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Should be able to delete the var

+  // NOTE: some implementations of VP will require the musthave a= ttributes to be passed even when deleting

+  //

+  Status =3D gRT->SetVariable (L"MustHaveAttrWildcardNoLo= ckVar5612",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  return UNIT_TEST_PASSED;

+} // TestMustHaveAttrWildcardNoLock

+

+UNIT_TEST_STATUS

+EFIAPI

+TestPolicyprioritizationNoLock (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT8      Value8;

+  UINT16     Value16;

+  UINT32     Value32;

+  UINT64     Value64;

+

+  //

+  // Register a policy targeting the specific var

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid3,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"PolicyPriorityTestVar123",

+           &nbs= p;            &= nbsp;           &nbs= p;   8, // min size of UINT64

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Register a policy with wildcards in the name

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid3,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"PolicyPriorityTestVar###",

+           &nbs= p;            &= nbsp;           &nbs= p;   4, // min size of UINT32

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Register a policy with wildcards in the name

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid3,

+           &nbs= p;            &= nbsp;           &nbs= p;   NULL,

+           &nbs= p;            &= nbsp;           &nbs= p;   2, // min size of UINT16

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // The idea is that the most specific policy is applied:

+  //   For varname "TestVar", the namespace-w= ide one should apply: UINT16 minimum

+  //   For varname "PolicyPriorityTestVar567"= the wildcard policy should apply: UINT32 minimum

+  //   For varname "PolicyPriorityTestVar123"= the var-specific policy should apply: UINT64 minimum

+  //

+

+  //

+  // Let's confirm the namespace-wide policy enforcement

+  //

+  Value8 =3D 0x78;

+  Status =3D gRT->SetVariable (L"TestVar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid3,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value8),

+           &nbs= p;            &= nbsp;    &Value8);

+  UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status = =3D=3D EFI_INVALID_PARAMETER));

+

+  Value16 =3D 0x6543;

+  Status =3D gRT->SetVariable (L"TestVar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid3,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value16),

+           &nbs= p;            &= nbsp;    &Value16);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Let's confirm the wildcard policy enforcement

+  //

+  Value16 =3D 0xabba;

+  Status =3D gRT->SetVariable (L"PolicyPriorityTestVar567= ",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid3,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value16),

+           &nbs= p;            &= nbsp;    &Value16);

+  UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status = =3D=3D EFI_INVALID_PARAMETER));

+

+  Value32 =3D 0xfedcba98;

+  Status =3D gRT->SetVariable (L"PolicyPriorityTestVar567= ",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid3,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value32),

+           &nbs= p;            &= nbsp;    &Value32);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Let's confirm the var-specific policy enforcement

+  //

+  Value32 =3D 0x8d3f627c;

+  Status =3D gRT->SetVariable (L"PolicyPriorityTestVar123= ",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid3,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value32),

+           &nbs= p;            &= nbsp;    &Value32);

+  UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status = =3D=3D EFI_INVALID_PARAMETER));

+

+  Value64 =3D 0xbebecdcdafaf6767;

+  Status =3D gRT->SetVariable (L"PolicyPriorityTestVar123= ",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid3,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value64),

+           &nbs= p;            &= nbsp;    &Value64);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  return UNIT_TEST_PASSED;

+} // TestPolicyprioritizationNoLock

+

+/**

+  LockNow Policy tests.

+**/

+UNIT_TEST_STATUS

+EFIAPI

+TestExistingVarLockNow (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT8      Value;

+

+  //

+  // Write a var that we'll protect next

+  //

+  Value =3D 0x78;

+  Status =3D gRT->SetVariable (L"ExistingLockNowVar"= ,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Register a LockNow policy targeting the var

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"ExistingLockNowVar",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_LOCK_NOW);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Attempt to modify the locked var

+  //

+  Value =3D 0xA5;

+  Status =3D gRT->SetVariable (L"ExistingLockNowVar"= ,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);

+

+  //

+  // Attempt to delete the locked var

+  //

+  Status =3D gRT->SetVariable (L"ExistingLockNowVar"= ,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);

+

+  //

+  // This variable is deleted in final cleanup.

+  //

+

+  return UNIT_TEST_PASSED;

+} // TestExistingVarLockNow

+

+UNIT_TEST_STATUS

+EFIAPI

+TestNonexistentVarLockNow (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT8      Value;

+  UINTN      Size;

+

+  //

+  // Make sure the variable we're about to create the policy for = doesn't exist

+  //

+  Size =3D 0;

+  Status =3D gRT->GetVariable (L"NonexistentLockNowVar&qu= ot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    NULL,

+           &nbs= p;            &= nbsp;    &Size,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);

+

+  //

+  // Register a LockNow policy targeting the var

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"NonexistentLockNowVar",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_LOCK_NOW);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Attempt to create the locked var

+  //

+  Value =3D 0xA5;

+  Status =3D gRT->SetVariable (L"NonexistentLockNowVar&qu= ot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);

+

+  return UNIT_TEST_PASSED;

+} // TestNonexistentVarLockNow

+

+/**

+  LockOnCreate Policy tests.

+**/

+UNIT_TEST_STATUS

+EFIAPI

+TestExistingVarLockOnCreate (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT8      Value;

+

+  //

+  // Write a var that we'll protect later

+  //

+  Value =3D 0x78;

+  Status =3D gRT->SetVariable (L"ExistingLockOnCreateVar&= quot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Register a LockNow policy targeting the var

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"ExistingLockOnCreateVar",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_LOCK_ON_CREATE);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Attempt to modify the locked var

+  //

+  Value =3D 0xA5;

+  Status =3D gRT->SetVariable (L"ExistingLockOnCreateVar&= quot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);

+

+  //

+  // Attempt to delete the locked var

+  //

+  Status =3D gRT->SetVariable (L"ExistingLockOnCreateVar&= quot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);

+

+  //

+  // This variable is deleted in final cleanup.

+  //

+

+  return UNIT_TEST_PASSED;

+} // TestExistingVarLockOnCreate

+

+UNIT_TEST_STATUS

+EFIAPI

+TestNonexistentVarLockOnCreate (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT8      Value1;

+  UINT32     Value2;

+  UINTN      Size;

+

+  //

+  // Make sure the variable we're about to create the policy for = doesn't exist

+  //

+  Size =3D 0;

+  Status =3D gRT->GetVariable (L"NonexistentLockOnCreateV= ar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    NULL,

+           &nbs= p;            &= nbsp;    &Size,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);

+

+  //

+  // Register a LockOnCreate policy targeting the var

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"NonexistentLockOnCreateVar",

+           &nbs= p;            &= nbsp;           &nbs= p;   2, // min size of 2 bytes, UINT16+

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   EFI_VARIABLE_RUNTIME_ACCESS, // must have RT attr

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_LOCK_ON_CREATE);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Attempt to create the var, but smaller than min size

+  //

+  Value1 =3D 0xA5;

+  Status =3D gRT->SetVariable (L"NonexistentLockOnCreateV= ar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUN= TIME_ACCESS | EFI_VARIABLE_NON_VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value1),

+           &nbs= p;            &= nbsp;    &Value1);

+  UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status = =3D=3D EFI_INVALID_PARAMETER));

+

+  //

+  // Now let's make sure attribute req is enforced

+  //

+  Value2 =3D 0x43218765;

+  Status =3D gRT->SetVariable (L"NonexistentLockOnCreateV= ar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value2),

+           &nbs= p;            &= nbsp;    &Value2);

+  UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status = =3D=3D EFI_INVALID_PARAMETER));

+

+  //

+  // Now let's create a valid variable

+  //

+  Value2 =3D 0x43218765;

+  Status =3D gRT->SetVariable (L"NonexistentLockOnCreateV= ar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUN= TIME_ACCESS | EFI_VARIABLE_NON_VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value2),

+           &nbs= p;            &= nbsp;    &Value2);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Let's make sure we can't modify it

+  //

+  Value2 =3D 0xa5a5b6b6;

+  Status =3D gRT->SetVariable (L"NonexistentLockOnCreateV= ar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUN= TIME_ACCESS | EFI_VARIABLE_NON_VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value2),

+           &nbs= p;            &= nbsp;    &Value2);

+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);

+

+  //

+  // Finally, let's make sure we can't delete it

+  //

+  Status =3D gRT->SetVariable (L"NonexistentLockOnCreateV= ar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);

+

+  //

+  // This variable is deleted in final cleanup.

+  //

+

+  return UNIT_TEST_PASSED;

+} // TestNonexistentVarLockOnCreate

+

+/**

+  LockOnVarState Policy tests.

+**/

+UNIT_TEST_STATUS

+EFIAPI

+TestLockOnVarStateBeforeCreate (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINTN      Size;

+  UINT8      Value;

+

+  //

+  // First of all, let's make sure the var we're trying to protec= t doesn't exist

+  //

+  Size =3D 0;

+  Status =3D gRT->GetVariable (L"NonexistentLockOnVarStat= eVar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    NULL,

+           &nbs= p;            &= nbsp;    &Size,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND);

+

+  //

+  // Good, now let's create a policy

+  //

+  Status =3D RegisterVarStateVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;      &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;      L"NonexistentLockOnVarStateVar",=

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;      &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;      L"Trigger1",

+           &nbs= p;            &= nbsp;           &nbs= p;      0x7E);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Now we write the trigger var

+  //

+  Value =3D 0x7E;

+  Status =3D gRT->SetVariable (L"Trigger1",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Ok, now we attempt to write a var protected by the trigger
+  //

+  Value =3D 0xFA;

+  Status =3D gRT->SetVariable (L"NonexistentLockOnVarStat= eVar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);

+

+  //

+  // Let's modify the trigger var and "untrigger" the p= olicy

+  //

+  Value =3D 0x38;

+  Status =3D gRT->SetVariable (L"Trigger1",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Now we should be able to create the var targeted by the poli= cy

+  //

+  Value =3D 0x23;

+  Status =3D gRT->SetVariable (L"NonexistentLockOnVarStat= eVar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Cleanup: delete the trigger and the protected var

+  //

+  Status =3D gRT->SetVariable (L"Trigger1",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  Status =3D gRT->SetVariable (L"NonexistentLockOnVarStat= eVar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  return UNIT_TEST_PASSED;

+} // TestLockOnVarStateBeforeCreate

+

+UNIT_TEST_STATUS

+EFIAPI

+TestLockOnVarStateAfterCreate (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT8      Value;

+

+  //

+  // Let's create a policy

+  //

+  Status =3D RegisterVarStateVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;      &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;      L"ExistingLockOnVarStateVar",
+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;      &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;      L"Trigger2",

+           &nbs= p;            &= nbsp;           &nbs= p;      0x5C);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Should be able to write targeted var since the policy isn't = active yet.

+  //

+  Value =3D 0x17;

+  Status =3D gRT->SetVariable (L"ExistingLockOnVarStateVa= r",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Let's modify the var to make sure the policy isn't acting li= ke a lock-on-create one

+  //

+  Value =3D 0x30;

+  Status =3D gRT->SetVariable (L"ExistingLockOnVarStateVa= r",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Now we trigger the policy

+  //

+  Value =3D 0x5C;

+  Status =3D gRT->SetVariable (L"Trigger2",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Let's now verify the variable is protected

+  //

+  Value =3D 0xB9;

+  Status =3D gRT->SetVariable (L"ExistingLockOnVarStateVa= r",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);

+

+  //

+  // Ok, to clean up, we need to remove the trigger var, so delet= e it, and then delete the target var

+  //

+  Status =3D gRT->SetVariable (L"Trigger2",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  Status =3D gRT->SetVariable (L"ExistingLockOnVarStateVa= r",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  return UNIT_TEST_PASSED;

+} // TestLockOnVarStateAfterCreate

+

+UNIT_TEST_STATUS

+EFIAPI

+TestLockOnVarStateInvalidLargeTrigger (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT16     Value;

+

+  //

+  // First let's create a variable policy

+  //

+  Status =3D RegisterVarStateVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;      &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;      L"InvalidLargeTriggerLockOnVarStateVa= r",

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;      &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;      L"Trigger3",

+           &nbs= p;            &= nbsp;           &nbs= p;      0x5C);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Now attempt to trigger the lock but with a variable larger t= han one byte

+  //

+  Value =3D 0x8085;

+  Status =3D gRT->SetVariable (L"Trigger3",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Should still be able to create the targeted var

+  //

+  Value =3D 0x1234;

+  Status =3D gRT->SetVariable (L"InvalidLargeTriggerLockO= nVarStateVar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Let's clean up by deleting the invalid trigger and the targe= ted var

+  //

+  Status =3D gRT->SetVariable (L"Trigger3",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  Status =3D gRT->SetVariable (L"InvalidLargeTriggerLockO= nVarStateVar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  return UNIT_TEST_PASSED;

+} // TestLockOnVarStateInvalidLargeTrigger

+

+UNIT_TEST_STATUS

+EFIAPI

+TestLockOnVarStateWrongValueTrigger (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT8      Value;

+

+  //

+  // First let's create a variable policy

+  //

+  Status =3D RegisterVarStateVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;      &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;      L"WrongValueTriggerLockOnVarStateVar&= quot;,

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;      VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;      &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;      L"Trigger4",

+           &nbs= p;            &= nbsp;           &nbs= p;      0xCA);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Now attempt to trigger the lock but with a wrong value

+  //

+  Value =3D 0x80;

+  Status =3D gRT->SetVariable (L"Trigger4",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Should still be able to create the targeted var

+  //

+  Value =3D 0x14;

+  Status =3D gRT->SetVariable (L"WrongValueTriggerLockOnV= arStateVar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Let's clean up by deleting the invalid trigger and the targe= ted var

+  //

+  Status =3D gRT->SetVariable (L"Trigger4",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  Status =3D gRT->SetVariable (L"WrongValueTriggerLockOnV= arStateVar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  return UNIT_TEST_PASSED;

+} // TestLockOnVarStateWrongValueTrigger

+

+/**

+  Invalid policy tests.

+**/

+UNIT_TEST_STATUS

+EFIAPI

+TestInvalidAttributesPolicy (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  // The only must/can't have attributes supported by VPE are NV,= BS, and RT. They are 1, 2, and 4, respectively.

+  // Let's try some bits higher than that?

+  //

+

+  //

+  // Trying must have attribute 0x8 which is EFI_VARIABLE_HARDWAR= E_ERROR_RECORD

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"InvalidMustHaveAttributesPolicyVar1",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   EFI_VARIABLE_HARDWARE_ERROR_RECORD,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_HARDW= ARE_ERROR_RECORD returned %r\n", Status);

+

+  //

+  // Let's try 0x10 - EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, a = deprecated attribute

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"InvalidMustHaveAttributesPolicyVar2",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_AUTHE= NTICATED_WRITE_ACCESS returned %r\n", Status);

+

+  //

+  // Let's try 0x20 - EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE= _ACCESS

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"InvalidMustHaveAttributesPolicyVar3",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_LOG_INFO ("Setting must have attr to EFI_VARIABLE_TIME_= BASED_AUTHENTICATED_WRITE_ACCESS returned %r\n", Status);

+

+  //

+  // Let's try something wild, like 0x4000

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"InvalidMustHaveAttributesPolicyVar4",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   0x4000,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_LOG_INFO ("Setting must have attr to 0x4000 returned %r= \n", Status);

+

+  //

+  // Now repeat the same tests, but for the can't-have param

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"InvalidCantHaveAttributesPolicyVar1",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   EFI_VARIABLE_HARDWARE_ERROR_RECORD,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_HARDW= ARE_ERROR_RECORD returned %r\n", Status);

+

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"InvalidCantHaveAttributesPolicyVar2",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_AUTHE= NTICATED_WRITE_ACCESS returned %r\n", Status);

+

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"InvalidCantHaveAttributesPolicyVar3",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_LOG_INFO ("Setting cant have attr to EFI_VARIABLE_TIME_= BASED_AUTHENTICATED_WRITE_ACCESS returned %r\n", Status);

+

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"InvalidCantHaveAttributesPolicyVar4",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   0x4000,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  UT_LOG_INFO ("Setting cant have attr to 0x4000 returned %r= \n", Status);

+

+  return UNIT_TEST_PASSED;

+} // TestInvalidAttributesPolicy

+

+UNIT_TEST_STATUS

+EFIAPI

+TestLargeMinSizePolicy (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  // Let's set the min size to 2GB and see what happens

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"LargeMinSizeInvalidPolicyVar",

+           &nbs= p;            &= nbsp;           &nbs= p;   0x80000000,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+

+  UT_LOG_INFO ("Setting min size to 0x80000000 returned %r\n= ", Status);

+

+  return UNIT_TEST_PASSED;

+} // TestLargeMinSizePolicy

+

+UNIT_TEST_STATUS

+EFIAPI

+TestZeroMaxSizePolicy (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  // Let's set the max size to 0 and see what happens

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"ZeroMinSizeInvalidPolicyVar",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   0,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_NO_LOCK);

+  //UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS); // this fails on Q= C. Real bug? Do we care?

+  UT_LOG_INFO ("Setting max size to 0 returned %r\n", S= tatus);

+

+  return UNIT_TEST_PASSED;

+} // TestZeroMaxSizePolicy

+

+UNIT_TEST_STATUS

+EFIAPI

+TestInvalidPolicyTypePolicy (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  // Let's set policy type to an invalid value and see what happe= ns

+  // Valid ones are:

+  //        VARIABLE_POLICY_TY= PE_NO_LOCK           = ; 0

+  //        VARIABLE_POLICY_TY= PE_LOCK_NOW           1
+  //        VARIABLE_POLICY_TY= PE_LOCK_ON_CREATE     2

+  //        VARIABLE_POLICY_TY= PE_LOCK_ON_VAR_STATE  3

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"InvalidPolicyTypePolicyVar",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   4);

+  UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS);

+

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"InvalidPolicyTypePolicyVar",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   147);

+  UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS);

+

+  return UNIT_TEST_PASSED;

+} // TestInvalidPolicyTypePolicy

+

+/**

+  Test dumping policy.

+**/

+UNIT_TEST_STATUS

+EFIAPI

+TestDumpPolicy (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+  UINT8*     Buffer;

+  UINT32     Size;

+

+  //

+  // First let's call DumpVariablePolicy with null buffer to get = size

+  //

+  Size =3D 0;

+  Status =3D mVarPol->DumpVariablePolicy (NULL, &Size);
+  UT_ASSERT_STATUS_EQUAL (Status, EFI_BUFFER_TOO_SMALL);

+

+  //

+  // Now we allocate the buffer for the dump

+  //

+  Buffer =3D NULL;

+  Buffer =3D AllocatePool (Size);

+  UT_ASSERT_NOT_NULL (Buffer);

+

+  //

+  // Now we get the dump. In this test we will not analyze the du= mp.

+  //

+  Status =3D mVarPol->DumpVariablePolicy (Buffer, &Size);<= br>
+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  return UNIT_TEST_PASSED;

+} // TestDumpPolicy

+

+/**

+  Test policy version.

+**/

+UNIT_TEST_STATUS

+EFIAPI

+TestPolicyVersion (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS         = ;    Status;

+  VARIABLE_POLICY_ENTRY  *NewEntry;

+

+  //

+  // Create the new entry using a helper lib

+  //

+  NewEntry =3D NULL;

+  Status =3D CreateBasicVariablePolicy (&mTestNamespaceGuid1,=

+           &nbs= p;            &= nbsp;           &nbs= p; L"PolicyVersionTestNoLockVar",

+           &nbs= p;            &= nbsp;           &nbs= p; VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p; 4, // max size of 4 bytes

+           &nbs= p;            &= nbsp;           &nbs= p; VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p; VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p; VARIABLE_POLICY_TYPE_NO_LOCK,

+           &nbs= p;            &= nbsp;           &nbs= p; &NewEntry);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  NewEntry->Version =3D 0x1234;

+  Status =3D mVarPol->RegisterVariablePolicy (NewEntry);

+  UT_LOG_INFO ("Registering policy entry with an unknown ver= sion status: %r\n", Status);

+

+  FreePool (NewEntry);

+

+  return UNIT_TEST_PASSED;

+} // TestPolicyVersion

+

+/**

+  Lock Policy Tests.

+**/

+UNIT_TEST_STATUS

+EFIAPI

+LockPolicyEngineTests (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS  Status;

+  UINT16      Value;

+  UINT64      Value64;

+  BOOLEAN     State;

+

+  //

+  // First let's register a policy that we'll test after VPE lock=

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"BeforeVpeLockNoLockPolicyVar",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   4, // max size of 4 bytes

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_LOCK_ON_CREATE);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Now, lock VPE!

+  //

+  Status =3D mVarPol->LockVariablePolicy ();

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // See if we can lock it again?

+  //

+  Status =3D mVarPol->LockVariablePolicy ();

+  UT_LOG_INFO ("Locking VPE for second time returned %r\n&qu= ot;, Status);

+

+  //

+  // Let's confirm one of the policies from prior test suites is = still enforced

+  // Attempt to delete a locked var

+  //

+  Status =3D gRT->SetVariable (L"ExistingLockNowVar"= ,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);

+

+  //

+  // We'll make sure the policy from earlier in this test case is= actively filtering out by size

+  //

+  Value64 =3D 0x3829fed212345678;

+  Status =3D gRT->SetVariable (L"BeforeVpeLockNoLockPolic= yVar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS),

+           &nbs= p;            &= nbsp;    sizeof (Value64),

+           &nbs= p;            &= nbsp;    &Value64);

+  UT_ASSERT_TRUE ((Status =3D=3D EFI_WRITE_PROTECTED) || (Status = =3D=3D EFI_INVALID_PARAMETER));

+

+  //

+  // Let's create the variable from the policy now

+  //

+  Value =3D 0x323f;

+  Status =3D gRT->SetVariable (L"BeforeVpeLockNoLockPolic= yVar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Now confirm that the var is locked after creation

+  //

+  Value =3D 0x1212;

+  Status =3D gRT->SetVariable (L"BeforeVpeLockNoLockPolic= yVar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_NON_VOLATILE  | EFI_VARIABLE_BOO= TSERVICE_ACCESS),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_STATUS_EQUAL (Status, EFI_WRITE_PROTECTED);

+

+  //

+  // Let's attempt to register a new policy, it should fail

+  //

+  Status =3D RegisterBasicVariablePolicy (mVarPol,

+           &nbs= p;            &= nbsp;           &nbs= p;   &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;           &nbs= p;   L"AfterVpeLockNowPolicyVar",

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MIN_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MAX_SIZE,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_MUST_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_NO_CANT_ATTR,

+           &nbs= p;            &= nbsp;           &nbs= p;   VARIABLE_POLICY_TYPE_LOCK_NOW);

+  UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS);

+

+  //

+  // Make sure VPE is enabled

+  //

+  Status =3D mVarPol->IsVariablePolicyEnabled (&State);
+  UT_ASSERT_NOT_EFI_ERROR (Status);

+  UT_ASSERT_EQUAL (State, TRUE);

+

+  //

+  // Finally, make sure we can't disable VPE

+  //

+  Status =3D mVarPol->DisableVariablePolicy ();

+  UT_ASSERT_NOT_EQUAL (Status, EFI_SUCCESS);

+

+  return UNIT_TEST_PASSED;

+} // LockPolicyEngineTests

+

+/**

+  Save context and reboot after the lock policy test suite.

+**/

+STATIC

+VOID

+EFIAPI

+SaveContextAndReboot (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+

+  //

+  // Now, save all the data associated with this framework.

+  // TODO: Need to add to the UnitTestFrameworkPkg

+  Status =3D SaveFrameworkState( GetActiveFrameworkHandle(), NULL= , 0 );

+

+  //

+  // If we're all good, let's book...

+  if (!EFI_ERROR( Status ))

+  {

+    //

+    // Next, we want to update the BootNext variable to= USB

+    // so that we have a fighting chance of coming back= here.

+    //

+    // TODO: Need to add to the UnitTestFrameworkPkg
+    // SetBootNextDevice();

+

+    //

+    // Reset

+    DEBUG(( DEBUG_INFO, "%a - Rebooting! Launch th= is test again once booted.\n", __FUNCTION__ ));

+    gRT->ResetSystem( EfiResetCold, EFI_SUCCESS, 0, = NULL );

+    DEBUG(( DEBUG_ERROR, "%a - Unit test failed to= quit! Framework can no longer be used!\n", __FUNCTION__ ));

+

+    //

+    // We REALLY shouldn't be here.

+    Status =3D EFI_ABORTED;

+  }

+

+  return;

+} // SaveContextAndReboot

+

+/**

+  Disable policy tests.

+**/

+UNIT_TEST_STATUS

+EFIAPI

+DisablePolicyEngineTests (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS  Status;

+  BOOLEAN     State;

+  UINT8       Value;

+

+  //

+  // First, we disable the variable policy

+  //

+  Status =3D mVarPol->DisableVariablePolicy ();

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  //

+  // Confirm it's disabled

+  //

+  Status =3D mVarPol->IsVariablePolicyEnabled (&State);
+  UT_ASSERT_NOT_EFI_ERROR (Status);

+  UT_ASSERT_EQUAL (State, FALSE);

+

+  //

+  // Try locking it?

+  //

+  Status =3D mVarPol->LockVariablePolicy ();

+  UT_LOG_INFO ("Locking VP after disabling it status: %r\n&q= uot;, Status);

+

+  //

+  // Try modifying the var from TestExistingVarLockNow

+  //

+  Value =3D 0xB5;

+  Status =3D gRT->SetVariable (L"ExistingLockNowVar"= ,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON= _VOLATILE),

+           &nbs= p;            &= nbsp;    sizeof (Value),

+           &nbs= p;            &= nbsp;    &Value);

+  UT_ASSERT_NOT_EFI_ERROR (Status);

+

+  return UNIT_TEST_PASSED;

+} // DisablePolicyEngineTests

+

+/**

+  Final Cleanup: delete some variables earlier test cases created= .

+**/

+STATIC

+VOID

+EFIAPI

+FinalCleanup (

+  IN UNIT_TEST_CONTEXT       &= nbsp;   Context

+  )

+{

+  EFI_STATUS Status;

+

+  Status =3D gRT->SetVariable (L"ExistingLockNowVar"= ,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_LOG_INFO ("Delete ExistingLockNowVar status: %r\n"= , Status);

+

+  Status =3D gRT->SetVariable (L"ExistingLockOnCreateVar&= quot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_LOG_INFO ("Delete ExistingLockOnCreateVar status: %r\n&= quot;, Status);

+

+  Status =3D gRT->SetVariable (L"NonexistentLockOnCreateV= ar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_LOG_INFO ("Delete NonexistentLockOnCreateVar status: %r= \n", Status);

+

+  Status =3D gRT->SetVariable (L"NonexistentLockNowVar&qu= ot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_LOG_INFO ("Delete NonexistentLockNowVar status: %r\n&qu= ot;, Status);

+

+  Status =3D gRT->SetVariable (L"CantHaveAttrNoLockVar&qu= ot;,

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_LOG_INFO ("Delete CantHaveAttrNoLockVar status: %r\n&qu= ot;, Status);

+

+  Status =3D gRT->SetVariable (L"NonexistentLockOnVarStat= eVar",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_LOG_INFO ("Delete NonexistentLockOnVarStateVar status: = %r\n", Status);

+

+  Status =3D gRT->SetVariable (L"ExistingLockOnVarStateVa= r",

+           &nbs= p;            &= nbsp;    &mTestNamespaceGuid1,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    0,

+           &nbs= p;            &= nbsp;    NULL);

+  UT_LOG_INFO ("Delete ExistingLockOnVarStateVar status: %r\= n", Status);

+} // FinalCleanup

+

+/**

+

+  Main fuction sets up the unit test environment.

+

+**/

+EFI_STATUS

+EFIAPI

+UefiMain (

+  IN EFI_HANDLE        ImageHa= ndle,

+  IN EFI_SYSTEM_TABLE* SystemTable)

+{

+  EFI_STATUS         = ;         Status;

+  UNIT_TEST_FRAMEWORK_HANDLE  Framework;

+  UNIT_TEST_SUITE_HANDLE      GettingSta= rtedTestSuite;

+  UNIT_TEST_SUITE_HANDLE      NoLockPoli= ciesTestSuite;

+  UNIT_TEST_SUITE_HANDLE      LockNowPol= iciesTestSuite;

+  UNIT_TEST_SUITE_HANDLE      LockOnCrea= tePoliciesTestSuite;

+  UNIT_TEST_SUITE_HANDLE      LockOnVarS= tatePoliciesTestSuite;

+  UNIT_TEST_SUITE_HANDLE      InvalidPol= iciesTestSuite;

+  UNIT_TEST_SUITE_HANDLE      DumpPolicy= TestSuite;

+  UNIT_TEST_SUITE_HANDLE      PolicyVers= ionTestSuite;

+  UNIT_TEST_SUITE_HANDLE      LockPolicy= TestSuite;

+  UNIT_TEST_SUITE_HANDLE      DisablePol= icyTestSuite;

+

+  Framework =3D NULL;

+  GettingStartedTestSuite =3D NULL;

+  NoLockPoliciesTestSuite =3D NULL;

+  LockNowPoliciesTestSuite =3D NULL;

+  LockOnCreatePoliciesTestSuite =3D NULL;

+  LockOnVarStatePoliciesTestSuite =3D NULL;

+  InvalidPoliciesTestSuite =3D NULL;

+  DumpPolicyTestSuite =3D NULL;

+  PolicyVersionTestSuite =3D NULL; 

+  LockPolicyTestSuite =3D NULL;

+  DisablePolicyTestSuite =3D NULL;

+

+  DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, U= NIT_TEST_APP_VERSION));

+

+  //

+  // Start setting up the test framework for running the tests.
+  //

+  Status =3D InitUnitTestFramework (&Framework, UNIT_TEST_APP= _NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFr= amework. Status =3D %r\n", Status));

+    goto EXIT;

+  }

+

+  //

+  // Test suite 1: Getting Started. Get VP protocol, check state,= log revision

+  //

+  Status =3D CreateUnitTestSuite (&GettingStartedTestSuite, F= ramework, "Getting Started", "Common.VP.GettingStarted"= , NULL, NULL);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTest= Suite for the Getting Started Test Suite\n"));

+    Status =3D EFI_OUT_OF_RESOURCES;

+    goto EXIT;

+  }

+  AddTestCase (GettingStartedTestSuite, "Confirm VP is enabl= ed", "Common.VP.GettingStarted.CheckVpEnabled", CheckVpEnabl= ed, LocateVarPolicyPreReq, NULL, NULL);

+  AddTestCase (GettingStartedTestSuite, "Check VP revision&q= uot;, "Common.VP.GettingStarted.CheckVpRevision", CheckVpRevision= , LocateVarPolicyPreReq, NULL, NULL);

+

+  //

+  // Test suite 2: Test NoLock Policies

+  //

+  Status =3D CreateUnitTestSuite (&NoLockPoliciesTestSuite, F= ramework, "Exercise NoLock Policies", "Common.VP.NoLockPolic= ies", NULL, NULL);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTest= Suite for the NoLock Policies Test Suite\n"));

+    Status =3D EFI_OUT_OF_RESOURCES;

+    goto EXIT;

+  }

+  AddTestCase (NoLockPoliciesTestSuite, "Test Min Size enfor= cement in NoLock policy", "Common.VP.NoLockPolicies.TestMinSizeNo= Lock", TestMinSizeNoLock, LocateVarPolicyPreReq, NULL, NULL);

+  AddTestCase (NoLockPoliciesTestSuite, "Test Max Size enfor= cement in NoLock policy", "Common.VP.NoLockPolicies.TestMaxSizeNo= Lock", TestMaxSizeNoLock, LocateVarPolicyPreReq, NULL, NULL);

+  AddTestCase (NoLockPoliciesTestSuite, "Test Must Have Attr= ibute enforcement in NoLock policy", "Common.VP.NoLockPolicies.Te= stMustHaveAttrNoLock", TestMustHaveAttrNoLock, LocateVarPolicyPreReq, = NULL, NULL);

+  AddTestCase (NoLockPoliciesTestSuite, "Test Can't Have Att= ribute enforcement in NoLock policy", "Common.VP.NoLockPolicies.T= estCantHaveAttrNoLock", TestCantHaveAttrNoLock, LocateVarPolicyPreReq,= NULL, NULL);

+  AddTestCase (NoLockPoliciesTestSuite, "Test Max Size enfor= cement in NoLock policy for entire namespace", "Common.VP.NoLockP= olicies.TestMaxSizeNamespaceNoLock", TestMaxSizeNamespaceNoLock, Locat= eVarPolicyPreReq, NULL, NULL);

+  AddTestCase (NoLockPoliciesTestSuite, "Test Must Have Attr= ibute enforcement in NoLock policy with wildcards", "Common.VP.No= LockPolicies.TestMustHaveAttrWildcardNoLock", TestMustHaveAttrWildcard= NoLock, LocateVarPolicyPreReq, NULL, NULL);

+  AddTestCase (NoLockPoliciesTestSuite, "Test policy priorit= ization between namespace-wide, wildcard, and var-specific policies", = "Common.VP.NoLockPolicies.TestPolicyprioritizationNoLock", TestPo= licyprioritizationNoLock, LocateVarPolicyPreReq, NULL, NULL);

+

+  //

+  // Test suite 3: Test LockNow policies

+  //

+  Status =3D CreateUnitTestSuite (&LockNowPoliciesTestSuite, = Framework, "Exercise LockNow Policies", "Common.VP.LockNowPo= licies", NULL, NULL);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTest= Suite for the LockNow Policies Test Suite\n"));

+    Status =3D EFI_OUT_OF_RESOURCES;

+    goto EXIT;

+  }

+  AddTestCase (LockNowPoliciesTestSuite, "Test LockNow polic= y for a pre-existing variable", "Common.VP.LockNowPolicies.TestEx= istingVarLockNow", TestExistingVarLockNow, LocateVarPolicyPreReq, NULL= , NULL);

+  AddTestCase (LockNowPoliciesTestSuite, "Test LockNow polic= y for a nonexistent variable", "Common.VP.LockNowPolicies.TestNon= existentVarLockNow", TestNonexistentVarLockNow, LocateVarPolicyPreReq,= NULL, NULL);

+

+  //

+  // Test suite 4: Test LockOnCreate policies

+  //

+  Status =3D CreateUnitTestSuite (&LockOnCreatePoliciesTestSu= ite, Framework, "Exercise LockOnCreate Policies", "Common.VP= .LockOnCreate", NULL, NULL);

+  if (EFI_ERROR (Status))

+  {

+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTest= Suite for the LockOnCreate Policies Test Suite\n"));

+    Status =3D EFI_OUT_OF_RESOURCES;

+    goto EXIT;

+  }

+  AddTestCase (LockOnCreatePoliciesTestSuite, "Test LockOnCr= eate policy for a pre-existing variable", "Common.VP.LockOnCreate= .TestExistingVarLockOnCreate", TestExistingVarLockOnCreate, LocateVarP= olicyPreReq, NULL, NULL);

+  AddTestCase (LockOnCreatePoliciesTestSuite, "Test LockOnCr= eate policy for a nonexistent variable", "Common.VP.LockOnCreate.= TestNonexistentVarLockOnCreate", TestNonexistentVarLockOnCreate, Locat= eVarPolicyPreReq, NULL, NULL);

+

+  //

+  // Test suite 5: Test LockOnVarState policies

+  //

+  Status =3D CreateUnitTestSuite (&LockOnVarStatePoliciesTest= Suite, Framework, "Exercise LockOnVarState Policies", "Commo= n.VP.LockOnVarState", NULL, NULL);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTest= Suite for the LockOnVarState Policies Test Suite\n"));

+    Status =3D EFI_OUT_OF_RESOURCES;

+    goto EXIT;

+  }

+  AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOn= VarState policy for a nonexistent variable", "Common.VP.LockOnVar= State.TestLockOnVarStateBeforeCreate", TestLockOnVarStateBeforeCreate,= LocateVarPolicyPreReq, NULL, NULL);

+  AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOn= VarState policy for a pre-existing variable", "Common.VP.LockOnVa= rState.TestLockOnVarStateAfterCreate", TestLockOnVarStateAfterCreate, = LocateVarPolicyPreReq, NULL, NULL);

+  AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOn= VarState policy triggered by invalid-size variable", "Common.VP.L= ockOnVarState.TestLockOnVarStateInvalidLargeTrigger", TestLockOnVarSta= teInvalidLargeTrigger, LocateVarPolicyPreReq, NULL, NULL);

+  AddTestCase (LockOnVarStatePoliciesTestSuite, "Test LockOn= VarState policy triggered by invalid-value variable", "Common.VP.= LockOnVarState.TestLockOnVarStateWrongValueTrigger", TestLockOnVarStat= eWrongValueTrigger, LocateVarPolicyPreReq, NULL, NULL);

+

+  //

+  // Test suite 6: Test registering invalid policies

+  //

+  Status =3D CreateUnitTestSuite (&InvalidPoliciesTestSuite, = Framework, "Attempt registering invalid policies", "Common.V= P.InvalidPolicies", NULL, NULL);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTest= Suite for the Invalid Policies Test Suite\n"));

+    Status =3D EFI_OUT_OF_RESOURCES;

+    goto EXIT;

+  }

+  AddTestCase (InvalidPoliciesTestSuite, "Test policy with i= nvalid must-have attributes", "Common.VP.InvalidPolicies.TestInva= lidAttributesPolicy", TestInvalidAttributesPolicy, LocateVarPolicyPreR= eq, NULL, NULL);

+  AddTestCase (InvalidPoliciesTestSuite, "Test policy with i= nvalid attributes", "Common.VP.InvalidPolicies.TestLargeMinSizePo= licy", TestLargeMinSizePolicy, LocateVarPolicyPreReq, NULL, NULL);

+  AddTestCase (InvalidPoliciesTestSuite, "Test policy with i= nvalid attributes", "Common.VP.InvalidPolicies.TestZeroMaxSizePol= icy", TestZeroMaxSizePolicy, LocateVarPolicyPreReq, NULL, NULL);

+  AddTestCase (InvalidPoliciesTestSuite, "Test policy with i= nvalid type", "Common.VP.InvalidPolicies.TestInvalidPolicyTypePol= icy", TestInvalidPolicyTypePolicy, LocateVarPolicyPreReq, NULL, NULL);=

+

+  //

+  // Test suite 7: Test dumping the policy

+  //

+  Status =3D CreateUnitTestSuite (&DumpPolicyTestSuite, Frame= work, "Attempt dumping policy", "Common.VP.DumpPolicy",= NULL, NULL);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTest= Suite for the Dump Policy Test Suite\n"));

+    Status =3D EFI_OUT_OF_RESOURCES;

+    goto EXIT;

+  }

+  AddTestCase (DumpPolicyTestSuite, "Test dumping policy&quo= t;, "Common.VP.DumpPolicy.TestDumpPolicy", TestDumpPolicy, Locate= VarPolicyPreReq, NULL, NULL);

+

+  //

+  // Test suite 8: Test policy version

+  //

+  Status =3D CreateUnitTestSuite (&PolicyVersionTestSuite, Fr= amework, "Use non-zero policy version", "Common.VP.PolicyVer= sion", NULL, NULL);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTest= Suite for the Policy Version Test Suite\n"));

+    Status =3D EFI_OUT_OF_RESOURCES;

+    goto EXIT;

+  }

+  AddTestCase (PolicyVersionTestSuite, "Test policy version&= quot;, "Common.VP.DumpPolicy.TestPolicyVersion", TestPolicyVersio= n, LocateVarPolicyPreReq, NULL, NULL);

+

+  //

+  // Test suite 9: Lock VPE and test implications

+  //

+  Status =3D CreateUnitTestSuite (&LockPolicyTestSuite, Frame= work, "Lock policy, test it", "Common.VP.LockPolicyTests&quo= t;, NULL, NULL);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTest= Suite for the Lock Policy Test Suite\n"));

+    Status =3D EFI_OUT_OF_RESOURCES;

+    goto EXIT;

+  }

+  AddTestCase (LockPolicyTestSuite, "Test locking policy&quo= t;, "Common.VP.LockPolicyTests.LockPolicyEngineTests", LockPolicy= EngineTests, LocateVarPolicyPreReq, NULL, NULL);

+  AddTestCase (LockPolicyTestSuite, "Test locking policy&quo= t;, "Common.VP.LockPolicyTests.LockPolicyEngineTests", LockPolicy= EngineTests, LocateVarPolicyPreReq, SaveContextAndReboot, NULL);

+

+  //

+  // Test suite 10: Disable var policy and confirm expected behav= ior

+  //

+  Status =3D CreateUnitTestSuite (&DisablePolicyTestSuite, Fr= amework, "Disable policy, test it", "Common.VP.DisablePolicy= Tests", NULL, NULL);

+  if (EFI_ERROR (Status)) {

+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTest= Suite for the Disable Policy Test Suite\n"));

+    Status =3D EFI_OUT_OF_RESOURCES;

+    goto EXIT;

+  }

+  AddTestCase (DisablePolicyTestSuite, "Confirm VP is enable= d", "Common.VP.DisablePolicyTests.CheckVpEnabled", CheckVpEn= abled, LocateVarPolicyPreReq, NULL, NULL);

+  AddTestCase (DisablePolicyTestSuite, "Test LockNow policy = for a pre-existing variable", "Common.VP.DisablePolicyTests.TestE= xistingVarLockNow", TestExistingVarLockNow, LocateVarPolicyPreReq, NUL= L, NULL);

+  AddTestCase (DisablePolicyTestSuite, "Test disabling polic= y", "Common.VP.DisablePolicyTests.DisablePolicyEngineTests",= DisablePolicyEngineTests, LocateVarPolicyPreReq, FinalCleanup, NULL);

+

+  //

+  // Execute the tests.

+  //

+  Status =3D RunAllTestSuites (Framework);

+

+EXIT:

+  if (Framework !=3D NULL) {

+    FreeUnitTestFramework (Framework);

+  }

+

+  return Status;

+} // UefiMain

diff --git a/MdeModulePkg/MdeModulePkg.ci.yaml b/MdeModulePkg/MdeModulePkg.= ci.yaml
index 1cfc1328390e..88a192d0e2a8 100644
--- a/MdeModulePkg/MdeModulePkg.ci.yaml
+++ b/MdeModulePkg/MdeModulePkg.ci.yaml
@@ -35,7 +35,9 @@
             &q= uot;UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"

         ],

         # For UEFI shell based app= s

-        "AcceptableDependencies-UE= FI_APPLICATION":[],

+        "AcceptableDependencie= s-UEFI_APPLICATION":[

+            &qu= ot;UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"

+        ],

         "IgnoreInf": []<= br>
     },

 

diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc<= br> index f0a75a3b337b..414a6c62dfdb 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -19,6 +19,8 @@ [Defines]
   BUILD_TARGETS        &= nbsp;         =3D DEBUG|RELEASE|NOO= PT

   SKUID_IDENTIFIER       &nbs= p;       =3D DEFAULT

 

+!include UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc

+

 [LibraryClasses]

   #

   # Entry point

@@ -314,6 +316,10 @@ [Components]
   MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
   MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntim= eDxe.inf

   MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf
+  MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariableP= olicyFuncTestApp.inf {

+    <LibraryClasses>

+      UnitTestBootLib|UnitTestFrameworkPkg/Li= brary/UnitTestBootLibNull/UnitTestBootLibNull.inf

+  }

   MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf

   MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf

   MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf

diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.m= d b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Readme.md
new file mode 100644
index 000000000000..804ad4173a5f
--- /dev/null
+++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Rea= dme.md
@@ -0,0 +1,55 @@
+# variable Policy Unit Tests

+

+## &#x1F539; Copyright

+Copyright (C) Microsoft Corporation. All rights reserved.

+SPDX-License-Identifier: BSD-2-Clause-Patent

+

+## About This Test

+This test verifies functionality of the Variable Policy Protocol by re= gistering various variable policies and exercising them, as well as tests l= ocking the policy, disabling it, and dumping the policy entries.

+

+Only policies that are created as a part of this test will be tested.<= br>
+1. Try getting test context, if empty then get VP protocol, confirm th= at VP is not disabled by calling IsVariablePolicyEnabled. Log VP revision.<= br>
+2. "No lock" policies:

+    * check minsize enforcement

+    * check maxsize enforcement

+    * check musthave attr enforcement

+    * check canthave attr enforcement

+    * check one of the above with empty string policy i= .e. name wildcard

+    * check another one of the above with a "#&quo= t; containing policy string

+    * check policy prioritization by having a namespace= -wide policy, a policy with a # wildcard, and a one-var specific policy and= testing which one is enforced

+3. "Lock now" policies (means if the var doesn't exist, it w= on't be created; if one exists, it can't be updated):

+    * test a policy for an already existing variable, v= erify we can't write into that variable

+    * create a policy for a non-existing variable and a= ttempt to register such var

+4. "Lock on create" policies (means the var can still be cre= ated, but no updates later, existing vars can't be updated):

+    * create a var, lock it with LockOnCreate, attempt = to update its contents

+    * create LockOnCreate VP, attempt to create var wit= h invalid size, then invalid attr, then create valid var, attempt to update= its contents

+5. "Lock on var state" policies (means the var protected by = this policy can't be created or updated once the trigger is set)

+    * create VP, trigger lock with a valid var, attempt= to create a locked var, then modify the trigger var, create locked var

+    * create VP, create targeted var, modify it, trigge= r lock, attempt to modify var

+    * create VP, trigger lock with invalid (larger than= one byte) var, see if VPE allows creation of the locked var (it should all= ow)

+    * create VP, set locking var with wrong value, see = if VPE allows creation of the locked var (should allow)

+6. Attempt registering invalid policy entries

+    * invalid required and banned attributes

+    * large min size - let's say 2GB

+    * max size equal to 0

+    * invalid policy type

+7. Exercise dumping policy. No need to check the validity of the dump = blob.

+8. Test registering a policy with a random version.

+9. Lock VPE, make sure old policies are enforced, new ones can't be re= gistered.

+    * Register a LockOnCreate policy

+    * Lock VPE

+    * Test locking it again.

+    * Verify one of the prior policies is enforced

+    * Make sure we can create variables even if those a= re protected by LockOnCreate policy, after locking the VPE

+    * Attempt to register new policies

+    * Make sure can't disable VPE

+    * Cleanup: save context and reboot

+10. Disable variable policy and try some things

+    * Locate Variable Policy Protocol

+    * Make sure VP is enabled

+    * Register a policy

+    * Disable VPE

+    * Call IsVariablePolicyEnabled to confirm it's disa= bled.

+    * Make sure can't lock policy

+    * Make sure the policy from a is no longer enforced=

+    * Final cleanup: delete vars that were created in s= ome earlier test suites

diff --git a/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Variable= PolicyFuncTestApp.inf b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestA= pp/VariablePolicyFuncTestApp.inf
new file mode 100644
index 000000000000..9ad277a547c2
--- /dev/null
+++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/Var= iablePolicyFuncTestApp.inf
@@ -0,0 +1,42 @@
+## @file

+# Uefi Shell based Application that unit tests the Variable Policy Pro= tocol

+#

+# Copyright (c) Microsoft Corporation.

+# SPDX-License-Identifier: BSD-2-Clause-Patent

+##

+

+[Defines]

+  INF_VERSION        &nbs= p;           =3D 0x000100= 05

+  BASE_NAME         =              = =3D VariablePolicyFuncTestApp

+  FILE_GUID         =              = =3D B653C4C3-3FCC-4B6C-8051-5F692AEAECBA

+  MODULE_TYPE        &nbs= p;           =3D UEFI_APP= LICATION

+  VERSION_STRING        &= nbsp;        =3D 1.0

+  ENTRY_POINT        &nbs= p;           =3D UefiMain=

+

+#

+# The following information is for reference only and not required by = the build tools.

+#

+#  VALID_ARCHITECTURES       &= nbsp;   =3D X64 AARCH64

+#

+

+[Sources]

+  VariablePolicyFuncTestApp.c

+

+[Packages]

+  MdePkg/MdePkg.dec

+  MdeModulePkg/MdeModulePkg.dec

+  UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec

+

+[LibraryClasses]

+  UefiApplicationEntryPoint

+  BaseLib

+  UnitTestLib

+  UnitTestBootLib

+  PrintLib

+  UefiBootServicesTableLib

+  UefiRuntimeServicesTableLib

+  MemoryAllocationLib

+  VariablePolicyHelperLib

+

+[Protocols]

+  gEdkiiVariablePolicyProtocolGuid

--
2.26.2.windows.1.8.g01c50adf56.20200515075929


-=3D-=3D-=3D-=3D-=3D-=3D
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#60650): https://nam06.safelinks.protection.outlook.com/?url=3Dhttps%3A%2F%2Fedk2.gr= oups.io%2Fg%2Fdevel%2Fmessage%2F60650&amp;data=3D02%7C01%7Cbret.barkele= w%40microsoft.com%7C48059bf775454b7b4d2608d807a3e308%7C72f988bf86f141af91ab= 2d7cd011db47%7C1%7C0%7C637267747768910602&amp;sdata=3DlgY1iwLZRvqFnPCm3= Zmox4LalLdnrkxq8r155yNFbR4%3D&amp;reserved=3D0
Mute This Topic: https://nam06.safelinks.protection.outlook.com/?url=3Dhttps%3A%2F%2Fgroups.= io%2Fmt%2F74646439%2F1852292&amp;data=3D02%7C01%7Cbret.barkelew%40micro= soft.com%7C48059bf775454b7b4d2608d807a3e308%7C72f988bf86f141af91ab2d7cd011d= b47%7C1%7C0%7C637267747768910602&amp;sdata=3DCKFvSs5%2BCDn0Kaq%2F0MDLQM= lQ79HkviHQNBZde8tM5Ro%3D&amp;reserved=3D0
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://nam06.safelinks.protection.outlook.com/?url=3Dhttps%3A%2F%2Fedk2.gr= oups.io%2Fg%2Fdevel%2Funsub&amp;data=3D02%7C01%7Cbret.barkelew%40micros= oft.com%7C48059bf775454b7b4d2608d807a3e308%7C72f988bf86f141af91ab2d7cd011db= 47%7C1%7C0%7C637267747768910602&amp;sdata=3DHrb%2BQ%2FgFRUJ8%2F%2FD6bMb= saySdS0qu4aC5Iy2dMryQyrw%3D&amp;reserved=3D0  [bret.barkelew@microsoft.com]
-=3D-=3D-=3D-=3D-=3D-=3D

--_000_CY4PR21MB07431BB6A62B00E160B57138EF9A0CY4PR21MB0743namp_--