From nobody Fri Apr 19 22:02:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+69673+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+69673+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1609823141; cv=none; d=zohomail.com; s=zohoarc; b=d4hbqx2x6ce05aTEyAqj4MXWvq/o7nLQzCKrs9Fap+B0za1O/7OkBcx1Me7B3KYHVHKZO7CO/z8ueklg2tIifmREDsOmluAeo2d8Ni9+yAb/uV8gv/+Xl6fDV2adLNMJIXLakgeE9W85/7QAkcLGCiUtPGwjYSWLlSzBLPoW+2w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1609823141; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=TP61g/n2ofq2MynxN54T0DyFc9mrrSSCgUbkyJ8/fp4=; b=gmlVtQ+mJa+WWu5E/mYRIREye0/43E2y37plO1d8DD4+YXpD5OEER/48u6CvXr8Q1NNMoE8PpRAwkVuDG/SwEeTTDYxKj1mq/YPEmKjC1z3nPre/kMVG+HZfNc2mQHrJT63P5vvMqcVC3/sd8jO9uN5T1vrnpTZ82FEuIMU6Q5o= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+69673+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1609823141311919.7848058609583; Mon, 4 Jan 2021 21:05:41 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id HOtDYY1788612xrYe4q3iTqh; Mon, 04 Jan 2021 21:05:40 -0800 X-Received: from mga05.intel.com (mga05.intel.com []) by mx.groups.io with SMTP id smtpd.web08.1450.1609823138568417608 for ; Mon, 04 Jan 2021 21:05:40 -0800 IronPort-SDR: OERXxrNVFBKL37/ibmQiY8UqOzmFUEYVvYsIMty74PTG1vFLCGGbJtZAFYtkD//Qt2AHunxWiv yKopNoBQx5VQ== X-IronPort-AV: E=McAfee;i="6000,8403,9854"; a="261816973" X-IronPort-AV: E=Sophos;i="5.78,476,1599548400"; d="scan'208";a="261816973" X-Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jan 2021 21:05:31 -0800 IronPort-SDR: GWylwzLQ4tjpCGbZpasAZkQ6kMZaJzyeAnQauehhEKJfWYPVb1ScCpiHkVAOVpKLYn4KjtxlwE b6QTh+CBzIEA== X-IronPort-AV: E=Sophos;i="5.78,476,1599548400"; d="scan'208";a="378720577" X-Received: from mdkinney-mobl2.amr.corp.intel.com ([10.254.77.44]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Jan 2021 21:05:31 -0800 From: "Michael D Kinney" To: devel@edk2.groups.io Cc: Hao A Wu , Liming Gao , Bret Barkelew Subject: [edk2-devel] [stable/202011][Patch 2/2] MdeModulePkg/Variable/RuntimeDxe: Add Variable Lock Protocol Unit Tests Date: Mon, 4 Jan 2021 21:05:22 -0800 Message-Id: <20210105050522.1178-3-michael.d.kinney@intel.com> In-Reply-To: <20210105050522.1178-1-michael.d.kinney@intel.com> References: <20210105050522.1178-1-michael.d.kinney@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,michael.d.kinney@intel.com X-Gm-Message-State: xvBr3M3VH1o6JFJs2IgYwbKnx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1609823140; bh=7M6gSNqSN7/1jHUjEBFbf+WXtC2sp3q7aHTJyOfJvGQ=; h=Cc:Date:From:Reply-To:Subject:To; b=l6NsW4EAPbU8MW5PG1mozWlpDJ+7N00AM/Y2bqHYuBo34TPmkLyuikGGb0fXUoYBRrL G/DGPi92l5ogv/chGLA8Q0jYeUVgciOpvbdkDdGSO1dVrkI6oX3O5ZIYGcNXxagukJwTu CBEW6mZigUdOTf4e03bJWj/EVbirXr28CCw= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" https://bugzilla.tianocore.org/show_bug.cgi?id=3D3111 Add host based unit tests for the multiple lock case using Variable Lock Protocol, Variable Policy Protocol, and mixes of Variable Lock Protocol and Variable Policy Protocol. Cc: Michael D Kinney Cc: Hao A Wu Cc: Liming Gao Signed-off-by: Bret Barkelew Reviewed-by: Hao A Wu Reviewed-by: Liming Gao Reviewed-by: Michael D Kinney (cherry picked from commit dcaa93936591883aa7826eb45ef00416ad82ef08) --- MdeModulePkg/Test/MdeModulePkgHostTest.dsc | 11 + .../VariableLockRequestToLockUnitTest.c | 565 ++++++++++++++++++ .../VariableLockRequestToLockUnitTest.inf | 36 ++ 3 files changed, 612 insertions(+) create mode 100644 MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUn= itTest/VariableLockRequestToLockUnitTest.c create mode 100644 MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUn= itTest/VariableLockRequestToLockUnitTest.inf diff --git a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc b/MdeModulePkg/Test= /MdeModulePkgHostTest.dsc index 72a119db4568..4da4692c8451 100644 --- a/MdeModulePkg/Test/MdeModulePkgHostTest.dsc +++ b/MdeModulePkg/Test/MdeModulePkgHostTest.dsc @@ -19,6 +19,9 @@ [Defines] =20 !include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc =20 +[LibraryClasses] + SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf + [Components] MdeModulePkg/Library/DxeResetSystemLib/UnitTest/MockUefiRuntimeServicesT= ableLib.inf =20 @@ -30,3 +33,11 @@ [Components] ResetSystemLib|MdeModulePkg/Library/DxeResetSystemLib/DxeResetSystem= Lib.inf UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeResetSystemLib/U= nitTest/MockUefiRuntimeServicesTableLib.inf } + + MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/VariableLo= ckRequestToLockUnitTest.inf { + + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePol= icyLib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib= /VariablePolicyHelperLib.inf + + gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDisa= ble|TRUE + } diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/= VariableLockRequestToLockUnitTest.c b/MdeModulePkg/Universal/Variable/Runti= meDxe/RuntimeDxeUnitTest/VariableLockRequestToLockUnitTest.c new file mode 100644 index 000000000000..44d70e639d77 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Variabl= eLockRequestToLockUnitTest.c @@ -0,0 +1,565 @@ +/** @file + This is a host-based unit test for the VariableLockRequestToLock shim. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define UNIT_TEST_NAME "VarPol/VarLock Shim Unit Test" +#define UNIT_TEST_VERSION "1.0" + +///=3D=3D=3D CODE UNDER TEST =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +EFI_STATUS +EFIAPI +VariableLockRequestToLock ( + IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid + ); + +///=3D=3D=3D TEST DATA =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +// +// Test GUID 1 {F955BA2D-4A2C-480C-BFD1-3CC522610592} +// +EFI_GUID mTestGuid1 =3D { + 0xf955ba2d, 0x4a2c, 0x480c, {0xbf, 0xd1, 0x3c, 0xc5, 0x22, 0x61, 0x5, 0x= 92} +}; + +// +// Test GUID 2 {2DEA799E-5E73-43B9-870E-C945CE82AF3A} +// +EFI_GUID mTestGuid2 =3D { + 0x2dea799e, 0x5e73, 0x43b9, {0x87, 0xe, 0xc9, 0x45, 0xce, 0x82, 0xaf, 0x= 3a} +}; + +// +// Test GUID 3 {698A2BFD-A616-482D-B88C-7100BD6682A9} +// +EFI_GUID mTestGuid3 =3D { + 0x698a2bfd, 0xa616, 0x482d, {0xb8, 0x8c, 0x71, 0x0, 0xbd, 0x66, 0x82, 0x= a9} +}; + +#define TEST_VAR_1_NAME L"TestVar1" +#define TEST_VAR_2_NAME L"TestVar2" +#define TEST_VAR_3_NAME L"TestVar3" + +#define TEST_POLICY_ATTRIBUTES_NULL 0 +#define TEST_POLICY_MIN_SIZE_NULL 0 +#define TEST_POLICY_MAX_SIZE_NULL MAX_UINT32 + +#define TEST_POLICY_MIN_SIZE_10 10 +#define TEST_POLICY_MAX_SIZE_200 200 + +///=3D=3D=3D HELPER FUNCTIONS =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +/** + Mocked version of GetVariable, for testing. + + @param VariableName + @param VendorGuid + @param Attributes + @param DataSize + @param Data +**/ +EFI_STATUS +EFIAPI +StubGetVariableNull ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes, OPTIONAL + IN OUT UINTN *DataSize, + OUT VOID *Data OPTIONAL + ) +{ + UINT32 MockedAttr; + UINTN MockedDataSize; + VOID *MockedData; + EFI_STATUS MockedReturn; + + check_expected_ptr (VariableName); + check_expected_ptr (VendorGuid); + check_expected_ptr (DataSize); + + MockedAttr =3D (UINT32)mock(); + MockedDataSize =3D (UINTN)mock(); + MockedData =3D (VOID*)(UINTN)mock(); + MockedReturn =3D (EFI_STATUS)mock(); + + if (Attributes !=3D NULL) { + *Attributes =3D MockedAttr; + } + if (Data !=3D NULL && !EFI_ERROR (MockedReturn)) { + CopyMem (Data, MockedData, MockedDataSize); + } + + *DataSize =3D MockedDataSize; + + return MockedReturn; +} + +// +// Anything you think might be helpful that isn't a test itself. +// + +/** + This is a common setup function that will ensure the library is always + initialized with the stubbed GetVariable. + + Not used by all test cases, but by most. + + @param[in] Context Unit test case context +**/ +STATIC +UNIT_TEST_STATUS +EFIAPI +LibInitMocked ( + IN UNIT_TEST_CONTEXT Context + ) +{ + return EFI_ERROR (InitVariablePolicyLib (StubGetVariableNull)) ? UNIT_TE= ST_ERROR_PREREQUISITE_NOT_MET : UNIT_TEST_PASSED; +} + +/** + Common cleanup function to make sure that the library is always de-initi= alized + prior to the next test case. + + @param[in] Context Unit test case context +**/ +STATIC +VOID +EFIAPI +LibCleanup ( + IN UNIT_TEST_CONTEXT Context + ) +{ + DeinitVariablePolicyLib(); +} + +///=3D=3D=3D TEST CASES =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +///=3D=3D=3D=3D=3D SHIM SUITE =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +/** + Test Case that locks a single variable using the Variable Lock Protocol. + The call is expected to succeed. + + @param[in] Context Unit test case context +**/ +UNIT_TEST_STATUS +EFIAPI +LockingWithoutAnyPoliciesShouldSucceed ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NAME, &mTestGuid1= ); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} + +/** + Test Case that locks the same variable twice using the Variable Lock Pro= tocol. + Both calls are expected to succeed. + + @param[in] Context Unit test case context + **/ +UNIT_TEST_STATUS +EFIAPI +LockingTwiceShouldSucceed ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + + Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NAME, &mTestGuid1= ); + UT_ASSERT_NOT_EFI_ERROR (Status); + + Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NAME, &mTestGuid1= ); + UT_ASSERT_NOT_EFI_ERROR (Status); + + return UNIT_TEST_PASSED; +} + +/** + Test Case that locks a variable using the Variable Policy Protocol then = locks + the same variable using the Variable Lock Protocol. + Both calls are expected to succeed. + + @param[in] Context Unit test case context + **/ +UNIT_TEST_STATUS +EFIAPI +LockingALockedVariableShouldSucceed ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + VARIABLE_POLICY_ENTRY *NewEntry; + + // + // Create a variable policy that locks the variable. + // + Status =3D CreateBasicVariablePolicy ( + &mTestGuid1, + TEST_VAR_1_NAME, + TEST_POLICY_MIN_SIZE_NULL, + TEST_POLICY_MAX_SIZE_200, + TEST_POLICY_ATTRIBUTES_NULL, + TEST_POLICY_ATTRIBUTES_NULL, + VARIABLE_POLICY_TYPE_LOCK_NOW, + &NewEntry + ); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // + // Register the new policy. + // + Status =3D RegisterVariablePolicy (NewEntry); + + Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NAME, &mTestGuid1= ); + UT_ASSERT_NOT_EFI_ERROR (Status); + + FreePool (NewEntry); + + return UNIT_TEST_PASSED; +} + +/** + Test Case that locks a variable using the Variable Policy Protocol with a + policy other than LOCK_NOW then attempts to lock the same variable using= the + Variable Lock Protocol. The call to Variable Policy is expected to succ= eed + and the call to Variable Lock is expected to fail. + + @param[in] Context Unit test case context + **/ +UNIT_TEST_STATUS +EFIAPI +LockingAnUnlockedVariableShouldFail ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + VARIABLE_POLICY_ENTRY *NewEntry; + + // Create a variable policy that locks the variable. + Status =3D CreateVarStateVariablePolicy (&mTestGuid1, + TEST_VAR_1_NAME, + TEST_POLICY_MIN_SIZE_NULL, + TEST_POLICY_MAX_SIZE_200, + TEST_POLICY_ATTRIBUTES_NULL, + TEST_POLICY_ATTRIBUTES_NULL, + &mTestGuid2, + 1, + TEST_VAR_2_NAME, + &NewEntry); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Register the new policy. + Status =3D RegisterVariablePolicy (NewEntry); + + // Configure the stub to not care about parameters. We're testing errors. + expect_any_always( StubGetVariableNull, VariableName ); + expect_any_always( StubGetVariableNull, VendorGuid ); + expect_any_always( StubGetVariableNull, DataSize ); + + // With a policy, make sure that writes still work, since the variable d= oesn't exist. + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); // A= ttributes + will_return( StubGetVariableNull, 0 ); // S= ize + will_return( StubGetVariableNull, NULL ); // D= ataPtr + will_return( StubGetVariableNull, EFI_NOT_FOUND); // S= tatus + + Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NAME, &mTestGuid1= ); + UT_ASSERT_TRUE (EFI_ERROR (Status)); + + FreePool (NewEntry); + + return UNIT_TEST_PASSED; +} + +/** + Test Case that locks a variable using the Variable Policy Protocol with a + policy other than LOCK_NOW, but is currently locked. Then attempts to l= ock + the same variable using the Variable Lock Protocol. The call to Variable + Policy is expected to succeed and the call to Variable Lock also expecte= d to + succeed. + + @param[in] Context Unit test case context + **/ +UNIT_TEST_STATUS +EFIAPI +LockingALockedVariableWithMatchingDataShouldSucceed ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + VARIABLE_POLICY_ENTRY *NewEntry; + UINT8 Data; + + // Create a variable policy that locks the variable. + Status =3D CreateVarStateVariablePolicy (&mTestGuid1, + TEST_VAR_1_NAME, + TEST_POLICY_MIN_SIZE_NULL, + TEST_POLICY_MAX_SIZE_200, + TEST_POLICY_ATTRIBUTES_NULL, + TEST_POLICY_ATTRIBUTES_NULL, + &mTestGuid2, + 1, + TEST_VAR_2_NAME, + &NewEntry); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Register the new policy. + Status =3D RegisterVariablePolicy (NewEntry); + + // Configure the stub to not care about parameters. We're testing errors. + expect_any_always( StubGetVariableNull, VariableName ); + expect_any_always( StubGetVariableNull, VendorGuid ); + expect_any_always( StubGetVariableNull, DataSize ); + + // With a policy, make sure that writes still work, since the variable d= oesn't exist. + Data =3D 1; + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); // A= ttributes + will_return( StubGetVariableNull, sizeof (Data) ); // S= ize + will_return( StubGetVariableNull, &Data ); // D= ataPtr + will_return( StubGetVariableNull, EFI_SUCCESS); // S= tatus + + Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NAME, &mTestGuid1= ); + UT_ASSERT_TRUE (!EFI_ERROR (Status)); + + FreePool (NewEntry); + + return UNIT_TEST_PASSED; +} + +/** + Test Case that locks a variable using the Variable Policy Protocol with a + policy other than LOCK_NOW, but variable data does not match. Then atte= mpts + to lock the same variable using the Variable Lock Protocol. The call to + Variable Policy is expected to succeed and the call to Variable Lock is + expected to fail. + + @param[in] Context Unit test case context + **/ +UNIT_TEST_STATUS +EFIAPI +LockingALockedVariableWithNonMatchingDataShouldFail ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + VARIABLE_POLICY_ENTRY *NewEntry; + UINT8 Data; + + // Create a variable policy that locks the variable. + Status =3D CreateVarStateVariablePolicy (&mTestGuid1, + TEST_VAR_1_NAME, + TEST_POLICY_MIN_SIZE_NULL, + TEST_POLICY_MAX_SIZE_200, + TEST_POLICY_ATTRIBUTES_NULL, + TEST_POLICY_ATTRIBUTES_NULL, + &mTestGuid2, + 1, + TEST_VAR_2_NAME, + &NewEntry); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Register the new policy. + Status =3D RegisterVariablePolicy (NewEntry); + + // Configure the stub to not care about parameters. We're testing errors. + expect_any_always( StubGetVariableNull, VariableName ); + expect_any_always( StubGetVariableNull, VendorGuid ); + expect_any_always( StubGetVariableNull, DataSize ); + + // With a policy, make sure that writes still work, since the variable d= oesn't exist. + Data =3D 2; + will_return( StubGetVariableNull, TEST_POLICY_ATTRIBUTES_NULL ); // A= ttributes + will_return( StubGetVariableNull, sizeof (Data) ); // S= ize + will_return( StubGetVariableNull, &Data ); // D= ataPtr + will_return( StubGetVariableNull, EFI_SUCCESS); // S= tatus + + Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NAME, &mTestGuid1= ); + UT_ASSERT_TRUE (EFI_ERROR (Status)); + + FreePool (NewEntry); + + return UNIT_TEST_PASSED; +} + +/** + Test Case that locks a variable using Variable Lock Protocol Policy Prot= ocol + then and then attempts to lock the same variable using the Variable Poli= cy + Protocol. The call to Variable Lock is expected to succeed and the call= to + Variable Policy is expected to fail. + + @param[in] Context Unit test case context + **/ +UNIT_TEST_STATUS +EFIAPI +SettingPolicyForALockedVariableShouldFail ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + VARIABLE_POLICY_ENTRY *NewEntry; + + // Lock the variable. + Status =3D VariableLockRequestToLock (NULL, TEST_VAR_1_NAME, &mTestGuid1= ); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Create a variable policy that locks the variable. + Status =3D CreateVarStateVariablePolicy (&mTestGuid1, + TEST_VAR_1_NAME, + TEST_POLICY_MIN_SIZE_NULL, + TEST_POLICY_MAX_SIZE_200, + TEST_POLICY_ATTRIBUTES_NULL, + TEST_POLICY_ATTRIBUTES_NULL, + &mTestGuid2, + 1, + TEST_VAR_2_NAME, + &NewEntry); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Register the new policy. + Status =3D RegisterVariablePolicy (NewEntry); + UT_ASSERT_TRUE (EFI_ERROR (Status)); + + FreePool (NewEntry); + + return UNIT_TEST_PASSED; +} + +/** + Main entry point to this unit test application. + + Sets up and runs the test suites. +**/ +VOID +EFIAPI +UnitTestMain ( + VOID + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE ShimTests; + + Framework =3D NULL; + + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION)); + + // + // Start setting up the test framework for running the tests. + // + Status =3D InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCaller= BaseName, UNIT_TEST_VERSION); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status =3D %r\n= ", Status)); + goto EXIT; + } + + // + // Add all test suites and tests. + // + Status =3D CreateUnitTestSuite ( + &ShimTests, Framework, + "Variable Lock Shim Tests", "VarPolicy.VarLockShim", NULL, NU= LL + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for ShimTests\n")); + Status =3D EFI_OUT_OF_RESOURCES; + goto EXIT; + } + AddTestCase ( + ShimTests, + "Locking a variable with no matching policies should always work", "Em= ptyPolicies", + LockingWithoutAnyPoliciesShouldSucceed, LibInitMocked, LibCleanup, NULL + ); + AddTestCase ( + ShimTests, + "Locking a variable twice should always work", "DoubleLock", + LockingTwiceShouldSucceed, LibInitMocked, LibCleanup, NULL + ); + AddTestCase ( + ShimTests, + "Locking a variable that's already locked by another policy should wor= k", "LockAfterPolicy", + LockingALockedVariableShouldSucceed, LibInitMocked, LibCleanup, NULL + ); + AddTestCase ( + ShimTests, + "Locking a variable that already has an unlocked policy should fail", = "LockAfterUnlockedPolicy", + LockingAnUnlockedVariableShouldFail, LibInitMocked, LibCleanup, NULL + ); + AddTestCase ( + ShimTests, + "Locking a variable that already has an locked policy should succeed",= "LockAfterLockedPolicyMatchingData", + LockingALockedVariableWithMatchingDataShouldSucceed, LibInitMocked, Li= bCleanup, NULL + ); + AddTestCase ( + ShimTests, + "Locking a variable that already has an locked policy with matching da= ta should succeed", "LockAfterLockedPolicyNonMatchingData", + LockingALockedVariableWithNonMatchingDataShouldFail, LibInitMocked, Li= bCleanup, NULL + ); + AddTestCase ( + ShimTests, + "Adding a policy for a variable that has previously been locked should= always fail", "SetPolicyAfterLock", + SettingPolicyForALockedVariableShouldFail, LibInitMocked, LibCleanup, = NULL + ); + + // + // Execute the tests. + // + Status =3D RunAllTestSuites (Framework); + +EXIT: + if (Framework !=3D NULL) { + FreeUnitTestFramework (Framework); + } + + return; +} + +/// +/// Avoid ECC error for function name that starts with lower case letter +/// +#define Main main + +/** + Standard POSIX C entry point for host based unit test execution. + + @param[in] Argc Number of arguments + @param[in] Argv Array of pointers to arguments + + @retval 0 Success + @retval other Error +**/ +INT32 +Main ( + IN INT32 Argc, + IN CHAR8 *Argv[] + ) +{ + UnitTestMain (); + return 0; +} diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/= VariableLockRequestToLockUnitTest.inf b/MdeModulePkg/Universal/Variable/Run= timeDxe/RuntimeDxeUnitTest/VariableLockRequestToLockUnitTest.inf new file mode 100644 index 000000000000..2a659d7e1370 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/RuntimeDxeUnitTest/Variabl= eLockRequestToLockUnitTest.inf @@ -0,0 +1,36 @@ +## @file +# This is a host-based unit test for the VariableLockRequestToLock shim. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D VariableLockRequestToLockUnitTest + FILE_GUID =3D A7388B6C-7274-4717-9649-BDC5DFD1FCBE + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D HOST_APPLICATION + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 ARM AARCH64 +# + +[Sources] + VariableLockRequestToLockUnitTest.c + ../VariableLockRequestToLock.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[LibraryClasses] + UnitTestLib + DebugLib + VariablePolicyLib + VariablePolicyHelperLib + BaseMemoryLib + MemoryAllocationLib --=20 2.29.2.windows.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#69673): https://edk2.groups.io/g/devel/message/69673 Mute This Topic: https://groups.io/mt/79444821/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-