From nobody Sat May 18 02:37:22 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+68693+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+68693+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1607662326; cv=none; d=zohomail.com; s=zohoarc; b=cFfYGxeVBRHnxK17+ph/kpJiIR2LWG/y55BcFfhRVn9mAuE+WJh46LzFscyQfN4ZqQ+6ruF8W/cSVLAy971+TQ77FAwDwjOBKc0A/ok8YqzLpbsqTnXGjga2wEMe8uLfVapypMEexF9MQpuKoCDXog5qwD2hSfvnkc5nMGHaCEI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1607662326; 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=GNwRj1kU3/I7SBOXMmhvsSxyCuI1W94BqclQY52Oau4=; b=L9G3IKLpYCzbHZdTEquxfhBgiD24SRDxkgqcHDox0/XelbmCdQdNOKbNBj5hjwxnLTUSX/rh50L6C7omws4+W4l2jF7NjGElaf0MMYQ/MmkVCPwLpFWbm1Gc5pvwmY8zY7Oy8c+iDPuYxk0ccTTBDdcqBPHOWPIAOd1lJRqrJ0Y= 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+68693+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 1607662326588563.4142517742616; Thu, 10 Dec 2020 20:52:06 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id ea0nYY1788612x7t1h1bbE3e; Thu, 10 Dec 2020 20:52:06 -0800 X-Received: from mga04.intel.com (mga04.intel.com []) by mx.groups.io with SMTP id smtpd.web12.2414.1607662324935422813 for ; Thu, 10 Dec 2020 20:52:05 -0800 IronPort-SDR: veq4v3DWk3tpR/5AIfLixolFnd093z441zw+DecQFRK9IZpU6PBX7iuh0nJ6uJApPRgk0aY5/1 bjcEhN7GnwVQ== X-IronPort-AV: E=McAfee;i="6000,8403,9831"; a="171814622" X-IronPort-AV: E=Sophos;i="5.78,410,1599548400"; d="scan'208";a="171814622" X-Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Dec 2020 20:52:04 -0800 IronPort-SDR: 0vEATmm99BsXSXV4IDBDlEhzjm3UJE9LBgcNVV94FcpUmaXXkrtDvMcRDfdSF9yIqvH+M4tKIv iFfFJyEA7DiQ== X-IronPort-AV: E=Sophos;i="5.78,410,1599548400"; d="scan'208";a="349259486" X-Received: from mdkinney-mobl2.amr.corp.intel.com ([10.212.202.206]) by orsmga002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Dec 2020 20:52:03 -0800 From: "Michael D Kinney" To: devel@edk2.groups.io Cc: Bret Barkelew , Hao A Wu , Liming Gao , Bret Barkelew Subject: [edk2-devel] [Patch v3 1/2] MdeModulePkg/Variable/RuntimeDxe: Restore Variable Lock Protocol behavior Date: Thu, 10 Dec 2020 20:51:55 -0800 Message-Id: <20201211045156.1758-2-michael.d.kinney@intel.com> In-Reply-To: <20201211045156.1758-1-michael.d.kinney@intel.com> References: <20201211045156.1758-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: 5MYQXk2x6HK8dkBxAEynJo3Sx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1607662326; bh=8UcnSqFh4WcZDPZJuIKDQJmFhUefjAezB420wwByW0A=; h=Cc:Date:From:Reply-To:Subject:To; b=vbAm5LNNVJ/eMuVUUJ2dxf3KPmRUnZ4+8TMP8S6N0xJmP4n/WA1kYdfDgVasCnQRHSb wKJUj9gyH3Fs/l6+0qq2BpF3/OdeTmNEAlOhNlU2vmWtS3rQjYXasP8BARGn8z43+O/wN l0FJMBYS8r9OWx82mDzizQoVRwAymSRFpNU= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" From: Bret Barkelew https://bugzilla.tianocore.org/show_bug.cgi?id=3D3111 The VariableLock shim currently fails if called twice because the underlying Variable Policy engine returns an error if a policy is set on an existing variable. This breaks existing code which expect it to silently pass if a variable is locked multiple times (because it should "be locked"). Refactor the shim to confirm that the variable is indeed locked and then change the error to EFI_SUCCESS and generate a DEBUG_ERROR message so the duplicate lock can be reported in a debug log and removed. Cc: Michael D Kinney Cc: Hao A Wu Cc: Liming Gao Signed-off-by: Bret Barkelew --- .../RuntimeDxe/VariableLockRequestToLock.c | 95 ++++++++++++------- 1 file changed, 59 insertions(+), 36 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequest= ToLock.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequestTo= Lock.c index 4aa854aaf260..0715b527a0f7 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequestToLock.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequestToLock.c @@ -1,67 +1,90 @@ -/** @file -- VariableLockRequestToLock.c -Temporary location of the RequestToLock shim code while -projects are moved to VariablePolicy. Should be removed when deprecated. +/** @file + Temporary location of the RequestToLock shim code while projects + are moved to VariablePolicy. Should be removed when deprecated. =20 -Copyright (c) Microsoft Corporation. -SPDX-License-Identifier: BSD-2-Clause-Patent + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ =20 #include - #include #include - -#include - -#include #include #include - +#include =20 /** DEPRECATED. THIS IS ONLY HERE AS A CONVENIENCE WHILE PORTING. - Mark a variable that will become read-only after leaving the DXE phase o= f execution. - Write request coming from SMM environment through EFI_SMM_VARIABLE_PROTO= COL is allowed. + Mark a variable that will become read-only after leaving the DXE phase of + execution. Write request coming from SMM environment through + EFI_SMM_VARIABLE_PROTOCOL is allowed. =20 @param[in] This The VARIABLE_LOCK_PROTOCOL instance. - @param[in] VariableName A pointer to the variable name that will be mad= e read-only subsequently. - @param[in] VendorGuid A pointer to the vendor GUID that will be made = read-only subsequently. + @param[in] VariableName A pointer to the variable name that will be made + read-only subsequently. + @param[in] VendorGuid A pointer to the vendor GUID that will be made + read-only subsequently. =20 - @retval EFI_SUCCESS The variable specified by the VariableName= and the VendorGuid was marked - as pending to be read-only. + @retval EFI_SUCCESS The variable specified by the VariableName= and + the VendorGuid was marked as pending to be + read-only. @retval EFI_INVALID_PARAMETER VariableName or VendorGuid is NULL. Or VariableName is an empty string. - @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVE= NT_GROUP_READY_TO_BOOT has - already been signaled. - @retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the l= ock request. + @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or + EFI_EVENT_GROUP_READY_TO_BOOT has already = been + signaled. + @retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the l= ock + request. **/ EFI_STATUS EFIAPI VariableLockRequestToLock ( - IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid + IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid ) { - EFI_STATUS Status; - VARIABLE_POLICY_ENTRY *NewPolicy; + EFI_STATUS Status; + VARIABLE_POLICY_ENTRY *NewPolicy; + + DEBUG ((DEBUG_ERROR, "!!! DEPRECATED INTERFACE !!! %a() will go away soo= n!\n", __FUNCTION__)); + DEBUG ((DEBUG_ERROR, "!!! DEPRECATED INTERFACE !!! Please move to use Va= riable Policy!\n")); + DEBUG ((DEBUG_ERROR, "!!! DEPRECATED INTERFACE !!! Variable: %g %s\n", V= endorGuid, VariableName)); =20 NewPolicy =3D NULL; - Status =3D CreateBasicVariablePolicy( VendorGuid, - VariableName, - 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, - &NewPolicy ); + Status =3D CreateBasicVariablePolicy( + VendorGuid, + VariableName, + 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, + &NewPolicy + ); if (!EFI_ERROR( Status )) { - Status =3D RegisterVariablePolicy( NewPolicy ); + Status =3D RegisterVariablePolicy (NewPolicy); + + // + // If the error returned is EFI_ALREADY_STARTED, we need to check the + // current database for the variable and see whether it's locked. If i= t's + // locked, we're still fine, but also generate a DEBUG_ERROR message s= o the + // duplicate lock can be removed. + // + if (Status =3D=3D EFI_ALREADY_STARTED) { + Status =3D ValidateSetVariable (VariableName, VendorGuid, 0, sizeof(= ""), ""); + if (Status =3D=3D EFI_WRITE_PROTECTED) { + DEBUG ((DEBUG_ERROR, " Variable: %g %s is already locked!\n", Ven= dorGuid, VariableName)); + Status =3D EFI_SUCCESS; + } else { + DEBUG ((DEBUG_ERROR, " Variable: %g %s can not be locked!\n", Ven= dorGuid, VariableName)); + Status =3D EFI_ACCESS_DENIED; + } + } } - if (EFI_ERROR( Status )) { + if (EFI_ERROR (Status)) { DEBUG(( DEBUG_ERROR, "%a - Failed to lock variable %s! %r\n", __FUNCTI= ON__, VariableName, Status )); - ASSERT_EFI_ERROR( Status ); } if (NewPolicy !=3D NULL) { FreePool( NewPolicy ); --=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 (#68693): https://edk2.groups.io/g/devel/message/68693 Mute This Topic: https://groups.io/mt/78873159/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- From nobody Sat May 18 02:37:22 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+68694+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+68694+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1607662331; cv=none; d=zohomail.com; s=zohoarc; b=fXvxDZcspnG/BVxBzUlSAJllmBZmTOxj/JngwAWL3y2AwUqjqQEvFOmGLNC9TyzCb4oPfgkXm65LAPFsreof2zYjqeyv6l5rKfTwxA/fGUYdnFY0JAOzOk996CWJk7vOo2XtFnZtgBlnAvBaowQFOEdKN9AjsTW4TdJiTtoGkOk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1607662331; 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=I9FE/34+qJsDavqWJaXbQbBIxZ89JfxSwqpgkUp4qjY=; b=IZMKX1NPVmp6qxA9Zmta1TzDfq9mOiO5yi9MgFl1I705zxGispqwE4+79V6lIb09fNmESfOmy5r5Sg6S77QLC/4fk5N6F9qRBTW55vFxdVwe/Eq3cLqjSYeJHe60w+m2m2D+WxcsrQJ7+x3/YTo83Kd8VYHieclzv9Bs0JCFEbU= 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+68694+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 1607662331551841.1930350564971; Thu, 10 Dec 2020 20:52:11 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id mrOuYY1788612xPKGy7XURiV; Thu, 10 Dec 2020 20:52:11 -0800 X-Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mx.groups.io with SMTP id smtpd.web09.2373.1607662325547073181 for ; Thu, 10 Dec 2020 20:52:05 -0800 IronPort-SDR: i2Z7BtGOF3s5alSYRu3gxivf32PPvOdsbAmnAZ4VQwWzM67UAWnybZ4yK4wongqIe8bPboMYae 8P9sm62zzF6Q== X-IronPort-AV: E=McAfee;i="6000,8403,9831"; a="171814623" X-IronPort-AV: E=Sophos;i="5.78,410,1599548400"; d="scan'208";a="171814623" X-Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Dec 2020 20:52:04 -0800 IronPort-SDR: 3ltIhf2OqclOry+V/EWLWoF57hAjugjghs5Q1jL24Dn+yOIkQEcbX0U8MDGoPLusEMjpFfNAno VcZREKl7lNoA== X-IronPort-AV: E=Sophos;i="5.78,410,1599548400"; d="scan'208";a="349259495" X-Received: from mdkinney-mobl2.amr.corp.intel.com ([10.212.202.206]) by orsmga002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Dec 2020 20:52:03 -0800 From: "Michael D Kinney" To: devel@edk2.groups.io Cc: Hao A Wu , Liming Gao , Bret Barkelew Subject: [edk2-devel] [Patch v3 2/2] MdeModulePkg/Variable/RuntimeDxe: Add Variable Lock Protocol Unit Tests Date: Thu, 10 Dec 2020 20:51:56 -0800 Message-Id: <20201211045156.1758-3-michael.d.kinney@intel.com> In-Reply-To: <20201211045156.1758-1-michael.d.kinney@intel.com> References: <20201211045156.1758-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: 3ud3PDUOyZSBnz3vJwSSxz6Kx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1607662331; bh=KET/5H7LkSHO84mpT9YQfPEbIChfUdSZpGnQAhNJPmA=; h=Cc:Date:From:Reply-To:Subject:To; b=QxVk48l/zM+AtJPb2gegJHwjlB4i00lVMKaIWdLKEXx/YUvuDlKKbrwNqRYRRz5vC5K 1s/26DXhCiL2aHTmRwTX8AxxTxgyOCJtrTsRFfeNeb1Q4ZCw2qN+QWHffo+1sPj2C+qxR Ez+jf3D3a2x2a+/05iwfVs39x5RsQXDvcu4= 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 --- 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..a5bf720f42e1 --- /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= col. + 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= ced + 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 succced 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 succced 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 succced 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 (#68694): https://edk2.groups.io/g/devel/message/68694 Mute This Topic: https://groups.io/mt/78873160/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-