From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM02-BL2-obe.outbound.protection.outlook.com (NAM02-BL2-obe.outbound.protection.outlook.com [40.92.3.11]) by mx.groups.io with SMTP id smtpd.web10.3088.1590101118279072504 for ; Thu, 21 May 2020 15:45:18 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@outlook.com header.s=selector1 header.b=ZOIaQWGq; spf=pass (domain: outlook.com, ip: 40.92.3.11, mailfrom: michael.kubacki@outlook.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=SkSCtSEoEgt+0jVSQ9Tuq88A+iGZjMjXvdouaUAURTlbaCn7UIowoT6lYAMnLqCDsjhYq/ned7h8H3SEMTEJ0UlorwVC8OsJcQEumWzngjMpVhYtC74qIWdey/qmNW4B21g53jcqbmy9o+N5tIbqbBfHSHXd0QvgQizbXbj0fK5CeK7MN/WhrAKlMhFsdGtkCnDOUU5DPPrLAEgqm45mgaXsIhQg4pHrqADni/JyOJO7CSM2c2Hgo1W9fo9WfWf/b3fty7IWwUaSB9X3A4/N93gZ4Y2KhS7BnA4MdFga0efDaqAv6FTK8UkOYc6tcLeHQJxI84NtiwtT5RDQjsBdbA== 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=prLxwLGyATomRwYFUVzqzpcFpiSE+lnWPJlMjCAkq+8=; b=R1Cc8r6SsEiXrp1WrkHAr0QzSomAUa8dSofNQpHgWpdMF3Ahz6EVkA/wllewea++44n+rXWpZMfrAhk20F+GMyliZ1ghYdbRd1Wde27tSb81eraNTc/lHX8/s80mmlB5ylNU2jN+GmGBjZqxQQuDAP8lHWOM5jqAwBSgzpp4j6B9fJxbWlsWMyyOJusz7gQNRLTg4jbben644moBcQ46bnpbYi4IVxt/x6j8WgL+/+TQSRhQ8leEXlyuckH6kR8nz2DtwlG6HPblnkXOM4ov10z/FOiEN+Ly6zoQOoRFkD5IMvFiivyKoXwrLnAoppX+fVYmtgk+0LjOe/TqGO8hDQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=outlook.com; dmarc=pass action=none header.from=outlook.com; dkim=pass header.d=outlook.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=outlook.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=prLxwLGyATomRwYFUVzqzpcFpiSE+lnWPJlMjCAkq+8=; b=ZOIaQWGqxasa7I5MGziq4svgdspfJoTFCQu5nuMCBrab8x1M0NlHbDGVC4tsMq/wl5PtbM9UH7P+VtwGyeTtVUl09SnBnl2m8AxsJcOz5VUbrANUu2CTgXyl+9GA+mcQ6dephXlQAerVDmu2ztGttmhj0RHbws/sstb54MwvUgrf5UKwb8IgWLFuLgyJr6DsvCMuje7BmjtvdbpOcLXgR7qwGEZq37baNt9qHh4m9r9Tj8EIjVcuEiaHgEw66P97mX1+RDUE+N4jTlds9koDsa0U4dZ+c6O6xNeA1NVrwDeKtK/9tSwwU00zPX3+b04E/HPTMzPPLUSwLjtMLi9UVg== Received: from CY1NAM02FT003.eop-nam02.prod.protection.outlook.com (10.152.74.58) by CY1NAM02HT266.eop-nam02.prod.protection.outlook.com (10.152.74.99) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.23; Thu, 21 May 2020 22:45:16 +0000 Received: from MWHPR07MB3440.namprd07.prod.outlook.com (2a01:111:e400:7e45::53) by CY1NAM02FT003.mail.protection.outlook.com (2a01:111:e400:7e45::151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.23 via Frontend Transport; Thu, 21 May 2020 22:45:16 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:11EC11A31DF052ABFE35046E29D59C9B7E3333D4B1A323A8C1ABE3752AC94B4C;UpperCasedChecksum:6A923BD5828B435FC77A2E2C99F120B781419A2A1530CD3F2EA129D332919FFA;SizeAsReceived:7883;Count:50 Received: from MWHPR07MB3440.namprd07.prod.outlook.com ([fe80::bcc9:271b:20db:52e3]) by MWHPR07MB3440.namprd07.prod.outlook.com ([fe80::bcc9:271b:20db:52e3%6]) with mapi id 15.20.3021.020; Thu, 21 May 2020 22:45:16 +0000 From: "Michael Kubacki" To: devel@edk2.groups.io CC: Jian J Wang , Hao A Wu , Liming Gao , Bret Barkelew Subject: [PATCH v3 14/14] MdeModulePkg: Add a shell-based functional test for VariablePolicy Date: Thu, 21 May 2020 15:43:31 -0700 Message-ID: X-Mailer: git-send-email 2.16.3.windows.1 In-Reply-To: <20200521224331.15616-1-michael.kubacki@outlook.com> References: <20200521224331.15616-1-michael.kubacki@outlook.com> X-ClientProxiedBy: MWHPR12CA0071.namprd12.prod.outlook.com (2603:10b6:300:103::33) To MWHPR07MB3440.namprd07.prod.outlook.com (2603:10b6:301:69::28) Return-Path: michael.kubacki@outlook.com X-Microsoft-Original-Message-ID: <20200521224331.15616-15-michael.kubacki@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from localhost.localdomain (2001:4898:80e8:1:2c94:8481:fffa:8ac5) by MWHPR12CA0071.namprd12.prod.outlook.com (2603:10b6:300:103::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3021.23 via Frontend Transport; Thu, 21 May 2020 22:45:14 +0000 X-Mailer: git-send-email 2.16.3.windows.1 X-Microsoft-Original-Message-ID: <20200521224331.15616-15-michael.kubacki@outlook.com> X-TMN: [1XXFfDvhsFUI3kyj3lIlGRmJPSEOQ5CKpuUBalDwA2wUePifdHyDHnHkZBKVcOkW] X-MS-PublicTrafficType: Email X-IncomingHeaderCount: 50 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-Correlation-Id: cfd773e6-79b9-4e04-d3bb-08d7fdd8a0d8 X-MS-TrafficTypeDiagnostic: CY1NAM02HT266: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: KnD2AUIoJcIO7K7f50qYNLojZI0ATO4bqw5Kso9G6XDowTrW5RzmZwPVRYNgWVEHOmomIeM0IMGTAFCluF5nQUhXv5b6c4mNfUn/RazaawYb8LrrDVQGChQJHWql2yUDu8jjK8yMP7KlB+HHZBuBo1I45uW+mxljaRsCteRzOQii84Yedh5Q854An6Ggw6SUniKuT39Lz6H4bajTwM5HAczMm8rpD4I+3wuvt8sCPOLVxKqQ8tWwRde5qlJDlrYP X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:0;SRV:;IPV:NLI;SFV:NSPM;H:MWHPR07MB3440.namprd07.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:;DIR:OUT;SFP:1901; X-MS-Exchange-AntiSpam-MessageData: qzojdwt8gQ24lKpnqDmHr6yJzuuyeqnskJB7P0mh8k6AEbEX++7jpivwHWCwCI7bLGLa0h6QAyNMSEjC+kj+XjmRfi0CvI1J6dZE9arKjwEfLtxXGsUTsKLjYfu/Njrpn08BkLq2kM2ZDvjTFfdCqaEnGhOBLSm5b+yYX090P8qtjMzw5rhvtLkywXjiQ7J7zxV/dKk6SKIeJ5meXLDXKA== X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: cfd773e6-79b9-4e04-d3bb-08d7fdd8a0d8 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 May 2020 22:45:15.6828 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-FromEntityHeader: Internet X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1NAM02HT266 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain From: Bret Barkelew https://bugzilla.tianocore.org/show_bug.cgi?id=3D2522 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: Michael Kubacki --- MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyFuncTe= stApp.c | 1950 ++++++++++++++++++++ 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, 2056 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..0580fe6afda8 --- /dev/null +++ b/MdeModulePkg/Test/ShellTest/VariablePolicyFuncTestApp/VariablePolicyF= uncTestApp.c @@ -0,0 +1,1950 @@ +/** @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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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": [] }, =20 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 =20 +!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 --=20 2.16.3.windows.1