From nobody Tue Apr 30 19:24:51 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+67147+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+67147+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1604904368; cv=none; d=zohomail.com; s=zohoarc; b=cTVGAkNjWhAIEWE5Wy24aER/+3cBBtolC7LJTjYaTHqOwroiVeiQgq5FW68rBivR8s1Wyw+I1t4aWVq13yc2YT8UAA8wONAo2PyX0Z/6wdOtApKCqdO0JHNbslpEtnn/9h65nlQnA25QdOPC5Ce5YWqfZOUAFHdvzy4xeaxJc0A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604904368; 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=tTe4TRMFXwyCT3+NX7M81859qUzGjkRNrhGgYdW/Nns=; b=h26mhwDXBl4C/7dIsmnbWMMskfiAM7pMHQuFvz0CrMK2FBFyH0tAa3Xhul6Lhv/q79OdLlrnv5e23jxg/Plm8qamMXaEFFIhyYHLxTHEbPVanKt2NB3f30Iq8Dk7dogQvSNxcX3vM9kH5IdAqhT9Da90RusygDDWM/2c9V/MG4k= 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+67147+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 16049043683871022.7649736432297; Sun, 8 Nov 2020 22:46:08 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id U3LMYY1788612xq47VuVNDFv; Sun, 08 Nov 2020 22:46:08 -0800 X-Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) by mx.groups.io with SMTP id smtpd.web08.8042.1604904367409801470 for ; Sun, 08 Nov 2020 22:46:07 -0800 X-Received: by mail-pl1-f176.google.com with SMTP id w11so4255586pll.8 for ; Sun, 08 Nov 2020 22:46:07 -0800 (PST) X-Gm-Message-State: AX38LkJi1ZNqQHxlHWj6ew31x1787277AA= X-Google-Smtp-Source: ABdhPJyEnzhyO9jBHgNp2XcJ3iX7rJHT+ua4zD+5rsgEGjMebHGgXAStgSt9dLhLgPfgWXy6kACAmg== X-Received: by 2002:a17:902:b196:b029:d5:a8fd:9a1c with SMTP id s22-20020a170902b196b02900d5a8fd9a1cmr11808461plr.44.1604904366515; Sun, 08 Nov 2020 22:46:06 -0800 (PST) X-Received: from localhost.localdomain ([71.212.128.184]) by smtp.gmail.com with ESMTPSA id s145sm10215111pfs.187.2020.11.08.22.46.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Nov 2020 22:46:05 -0800 (PST) From: "Bret Barkelew" X-Google-Original-From: Bret Barkelew To: devel@edk2.groups.io Cc: Jian J Wang , Hao A Wu , Liming Gao , Bret Barkelew , Dandan Bi Subject: [edk2-devel] [PATCH v9 01/13] MdeModulePkg: Define the VariablePolicy protocol interface Date: Sun, 8 Nov 2020 22:45:10 -0800 Message-Id: <20201109064522.919-2-bret.barkelew@microsoft.com> In-Reply-To: <20201109064522.919-1-bret.barkelew@microsoft.com> References: <20201109064522.919-1-bret.barkelew@microsoft.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,bret@corthon.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604904368; bh=KJ5ZIvDLeSBPh7GB76iLF2hlBiQwdN9fmN7ysOYTr+w=; h=Cc:Date:From:Reply-To:Subject:To; b=akjwrK+b/MGUchYZxyteGCrpeerVOJPevoz1xrH2K+Ne6g6StqPwynJGFbtk1EL9PIM rFghkxZDOswsk+aVs09OGgJGbJmcZ3dDn6+47i9hQcqPqLcRS3ykBFjLu52RNmMR1zIdR n8O64Pcq1uEG8P7OLoLBcIX2ocw8IEQ8MbI= 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=3D2522 VariablePolicy is an updated interface to replace VarLock and VarCheckProtocol. Add the VariablePolicy protocol interface header and add to the MdeModulePkg.dec file. Cc: Jian J Wang Cc: Hao A Wu Cc: Liming Gao Cc: Bret Barkelew Signed-off-by: Bret Barkelew Reviewed-by: Dandan Bi Acked-by: Jian J Wang --- MdeModulePkg/Include/Protocol/VariablePolicy.h | 157 ++++++++++++++++++++ MdeModulePkg/MdeModulePkg.dec | 14 +- MdeModulePkg/MdeModulePkg.uni | 7 + 3 files changed, 177 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Include/Protocol/VariablePolicy.h b/MdeModulePkg/= Include/Protocol/VariablePolicy.h new file mode 100644 index 000000000000..8226c187a77b --- /dev/null +++ b/MdeModulePkg/Include/Protocol/VariablePolicy.h @@ -0,0 +1,157 @@ +/** @file -- VariablePolicy.h + +This protocol allows communication with Variable Policy Engine. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __EDKII_VARIABLE_POLICY_PROTOCOL__ +#define __EDKII_VARIABLE_POLICY_PROTOCOL__ + +#define EDKII_VARIABLE_POLICY_PROTOCOL_REVISION 0x0000000000010000 + +#define EDKII_VARIABLE_POLICY_PROTOCOL_GUID \ + { \ + 0x81D1675C, 0x86F6, 0x48DF, { 0xBD, 0x95, 0x9A, 0x6E, 0x4F, 0x09, 0x25= , 0xC3 } \ + } + +#define VARIABLE_POLICY_ENTRY_REVISION 0x00010000 + +#pragma pack(push, 1) +typedef struct { + UINT32 Version; + UINT16 Size; + UINT16 OffsetToName; + EFI_GUID Namespace; + UINT32 MinSize; + UINT32 MaxSize; + UINT32 AttributesMustHave; + UINT32 AttributesCantHave; + UINT8 LockPolicyType; + UINT8 Padding[3]; + // UINT8 LockPolicy[]; // Variable Length Field + // CHAR16 Name[] // Variable Length Field +} VARIABLE_POLICY_ENTRY; + +#define VARIABLE_POLICY_NO_MIN_SIZE 0 +#define VARIABLE_POLICY_NO_MAX_SIZE MAX_UINT32 +#define VARIABLE_POLICY_NO_MUST_ATTR 0 +#define VARIABLE_POLICY_NO_CANT_ATTR 0 + +#define VARIABLE_POLICY_TYPE_NO_LOCK 0 +#define VARIABLE_POLICY_TYPE_LOCK_NOW 1 +#define VARIABLE_POLICY_TYPE_LOCK_ON_CREATE 2 +#define VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE 3 + +typedef struct { + EFI_GUID Namespace; + UINT8 Value; + UINT8 Padding; + // CHAR16 Name[]; // Variable Length Field +} VARIABLE_LOCK_ON_VAR_STATE_POLICY; +#pragma pack(pop) + +/** + This API function disables the variable policy enforcement. If it's + already been called once, will return EFI_ALREADY_STARTED. + + @retval EFI_SUCCESS + @retval EFI_ALREADY_STARTED Has already been called once this boot. + @retval EFI_WRITE_PROTECTED Interface has been locked until reboot. + @retval EFI_WRITE_PROTECTED Interface option is disabled by platfo= rm PCD. + +**/ +typedef +EFI_STATUS +(EFIAPI *DISABLE_VARIABLE_POLICY)( + VOID + ); + +/** + This API function returns whether or not the policy engine is + currently being enforced. + + @param[out] State Pointer to a return value for whether the poli= cy enforcement + is currently enabled. + + @retval EFI_SUCCESS + @retval Others An error has prevented this command from compl= eting. + +**/ +typedef +EFI_STATUS +(EFIAPI *IS_VARIABLE_POLICY_ENABLED)( + OUT BOOLEAN *State + ); + +/** + This API function validates and registers a new policy with + the policy enforcement engine. + + @param[in] NewPolicy Pointer to the incoming policy structure. + + @retval EFI_SUCCESS + @retval EFI_INVALID_PARAMETER NewPolicy is NULL or is internally i= nconsistent. + @retval EFI_ALREADY_STARTED An identical matching policy already= exists. + @retval EFI_WRITE_PROTECTED The interface has been locked until = the next reboot. + @retval EFI_ABORTED A calculation error has prevented th= is function from completing. + @retval EFI_OUT_OF_RESOURCES Cannot grow the table to hold any mo= re policies. + +**/ +typedef +EFI_STATUS +(EFIAPI *REGISTER_VARIABLE_POLICY)( + IN CONST VARIABLE_POLICY_ENTRY *PolicyEntry + ); + +/** + This API function will dump the entire contents of the variable policy t= able. + + Similar to GetVariable, the first call can be made with a 0 size and it = will return + the size of the buffer required to hold the entire table. + + @param[out] Policy Pointer to the policy buffer. Can be NULL if Siz= e is 0. + @param[in,out] Size On input, the size of the output buffer. On outp= ut, the size + of the data returned. + + @retval EFI_SUCCESS Policy data is in the output buffer = and Size has been updated. + @retval EFI_INVALID_PARAMETER Size is NULL, or Size is non-zero an= d Policy is NULL. + @retval EFI_BUFFER_TOO_SMALL Size is insufficient to hold policy.= Size updated with required size. + +**/ +typedef +EFI_STATUS +(EFIAPI *DUMP_VARIABLE_POLICY)( + IN OUT UINT8 *Policy, + IN OUT UINT32 *Size + ); + +/** + This API function locks the interface so that no more policy updates + can be performed or changes made to the enforcement until the next boot. + + @retval EFI_SUCCESS + @retval Others An error has prevented this command from compl= eting. + +**/ +typedef +EFI_STATUS +(EFIAPI *LOCK_VARIABLE_POLICY)( + VOID + ); + +typedef struct { + UINT64 Revision; + DISABLE_VARIABLE_POLICY DisableVariablePolicy; + IS_VARIABLE_POLICY_ENABLED IsVariablePolicyEnabled; + REGISTER_VARIABLE_POLICY RegisterVariablePolicy; + DUMP_VARIABLE_POLICY DumpVariablePolicy; + LOCK_VARIABLE_POLICY LockVariablePolicy; +} _EDKII_VARIABLE_POLICY_PROTOCOL; + +typedef _EDKII_VARIABLE_POLICY_PROTOCOL EDKII_VARIABLE_POLICY_PROTOCOL; + +extern EFI_GUID gEdkiiVariablePolicyProtocolGuid; + +#endif diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index cb30a7975849..82aecc40d9a9 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -8,7 +8,7 @@ # Copyright (c) 2016, Linaro Ltd. All rights reserved.
# (C) Copyright 2016 - 2019 Hewlett Packard Enterprise Development LP
# Copyright (c) 2017, AMD Incorporated. All rights reserved.
-# Copyright (c) 2016, Microsoft Corporation
+# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -627,6 +627,9 @@ [Protocols] # 0x80000006 | Incorrect error code provided. # =20 + ## Include/Protocol/VariablePolicy.h + gEdkiiVariablePolicyProtocolGuid =3D { 0x81D1675C, 0x86F6, 0x48DF, { 0xB= D, 0x95, 0x9A, 0x6E, 0x4F, 0x09, 0x25, 0xC3 } } + [PcdsFeatureFlag] ## Indicates if the platform can support update capsule across a system = reset.

# TRUE - Supports update capsule across a system reset.
@@ -1119,6 +1122,15 @@ [PcdsFixedAtBuild, PcdsPatchableInModule] # @Prompt Variable storage size. gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x10000|UINT32|0x300= 00005 =20 + ## Toggle for whether the VariablePolicy engine should allow disabling. + # The engine is enabled at power-on, but the interface allows the platfo= rm to + # disable enforcement for servicing flexibility. If this PCD is disabled= , it will block the ability to + # disable the enforcement and VariablePolicy enforcement will always be = ON. + # TRUE - VariablePolicy can be disabled by request through the interfa= ce (until interface is locked) + # FALSE - VariablePolicy interface will not accept requests to disable= and is ALWAYS ON + # @Prompt Allow VariablePolicy enforcement to be disabled. + gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDisable|= FALSE|BOOLEAN|0x30000020 + ## FFS filename to find the ACPI tables. # @Prompt FFS name of ACPI tables storage. gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile|{ 0x25, 0x4e, 0x3= 7, 0x7e, 0x01, 0x8e, 0xee, 0x4f, 0x87, 0xf2, 0x39, 0xc, 0x23, 0xc6, 0x6, 0x= cd }|VOID*|0x30000016 diff --git a/MdeModulePkg/MdeModulePkg.uni b/MdeModulePkg/MdeModulePkg.uni index b8c867379a86..40884c57a460 100644 --- a/MdeModulePkg/MdeModulePkg.uni +++ b/MdeModulePkg/MdeModulePkg.uni @@ -129,6 +129,13 @@ =20 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdVariableStoreSize_HELP #lan= guage en-US "The size of volatile buffer. This buffer is used to store VOLA= TILE attribute variables." =20 +#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdAllowVariablePolicyEnforceme= ntDisable_PROMPT #language en-US "Allow VariablePolicy enforcement to be d= isabled." + +#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdAllowVariablePolicyEnforceme= ntDisable_HELP #language en-US "If this PCD is disabled, it will block the= ability to
\n" + = "disable the enforcement and VariablePolicy= enforcement will always be ON.
\n" + = "TRUE - VariablePolicy can be disabled by r= equest through the interface (until interface is locked)
\n" + = "FALSE - VariablePolicy interface will not = accept requests to disable and is ALWAYS ON
\n" + #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdAcpiTableStorageFile_PROMPT = #language en-US "FFS name of ACPI tables storage" =20 #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdAcpiTableStorageFile_HELP #= language en-US "FFS filename to find the ACPI tables." --=20 2.28.0.windows.1 -=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 (#67147): https://edk2.groups.io/g/devel/message/67147 Mute This Topic: https://groups.io/mt/78130768/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 Tue Apr 30 19:24:51 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+67148+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+67148+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1604904385; cv=none; d=zohomail.com; s=zohoarc; b=VwHXp7YH0bbBsS/j8beCTHQESr0Aex6Kbyb9mPCHl26WsjFmZ6DfMyqAcBWVn1PqGECljcVhvh2vx8qH9dDpcHNQr7ZIgrwjLgWDpVZKBW04oi20105p+9DgwaxmPT8Z1oN+rH09ps7s4ChMc/JOi+953sdatacJs1wATjQq37M= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604904385; 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=NDb8zI4mxJFjQV6D0rX0LUwfq/SR2G20Sy0v0TxzETQ=; b=QTolW5y4cOaipRRpDezve/pyNRF7uDdwLIbJgQOt+ajNFXt/elZ2Sfr1T0R2lyYgR7yBQiFfFwjueKOiBXNE48t2UGm8nAlID/t7gGbqRguQAMIdWsiq3iYl7sJ6kpe58XDX8E+1/jURcORbFRkK+b6XVDOFP32nqAy2EWmeUl0= 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+67148+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604904385010108.13683562136998; Sun, 8 Nov 2020 22:46:25 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 1YlAYY1788612xFH2CfmvLb5; Sun, 08 Nov 2020 22:46:24 -0800 X-Received: from mail-pg1-f177.google.com (mail-pg1-f177.google.com [209.85.215.177]) by mx.groups.io with SMTP id smtpd.web12.8023.1604904384120629979 for ; Sun, 08 Nov 2020 22:46:24 -0800 X-Received: by mail-pg1-f177.google.com with SMTP id r186so6317931pgr.0 for ; Sun, 08 Nov 2020 22:46:24 -0800 (PST) X-Gm-Message-State: Wpvl484y3WEtepvuXnbT41Mbx1787277AA= X-Google-Smtp-Source: ABdhPJxL6pX5mkxxzpHlmsOFj5m1RTukPON9guQRrt5L6ogkJSfLscDMQRVLBvEVaT5ziM7o8I3PEQ== X-Received: by 2002:a62:ee06:0:b029:164:20d:183b with SMTP id e6-20020a62ee060000b0290164020d183bmr12725132pfi.4.1604904382988; Sun, 08 Nov 2020 22:46:22 -0800 (PST) X-Received: from localhost.localdomain ([71.212.128.184]) by smtp.gmail.com with ESMTPSA id s145sm10215111pfs.187.2020.11.08.22.46.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Nov 2020 22:46:22 -0800 (PST) From: "Bret Barkelew" X-Google-Original-From: Bret Barkelew To: devel@edk2.groups.io Cc: Jian J Wang , Hao A Wu , Liming Gao , Bret Barkelew , Dandan Bi Subject: [edk2-devel] [PATCH v9 02/13] MdeModulePkg: Define the VariablePolicyLib Date: Sun, 8 Nov 2020 22:45:11 -0800 Message-Id: <20201109064522.919-3-bret.barkelew@microsoft.com> In-Reply-To: <20201109064522.919-1-bret.barkelew@microsoft.com> References: <20201109064522.919-1-bret.barkelew@microsoft.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,bret@corthon.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604904384; bh=VkMNcFXWPHxoOcRUaZNmVibjJZNpSZ04DwZ4Zue1TWE=; h=Cc:Date:From:Reply-To:Subject:To; b=ebDSOUNr0CkFU5A9mC1QTmU738fvJtNe2xvJQUdqu00XONK0nFqGxslF1xpLhW3bbpm ONgu3YFbizsqVkwelDXFMG7D+iegQEcDxA6moJoAVusqfDptcHIdA9q2SUeUNCIQoOuIE QqzLSRAeStqmVsgvSTyjhh5eSh1qYGgU0NQ= 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=3D2522 VariablePolicy is an updated interface to replace VarLock and VarCheckProtocol. Add the VariablePolicyLib library that implements the portable business logic for the VariablePolicy engine. Also add host-based CI test cases for the lib. Cc: Jian J Wang Cc: Hao A Wu Cc: Liming Gao Cc: Bret Barkelew Signed-off-by: Bret Barkelew Reviewed-by: Dandan Bi Acked-by: Jian J Wang --- MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c = | 46 ++ MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntimeDxe.c= | 85 ++ MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c = | 830 ++++++++++++++++++++ MdeModulePkg/Include/Library/VariablePolicyLib.h = | 207 +++++ MdeModulePkg/Library/VariablePolicyLib/ReadMe.md = | 406 ++++++++++ MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf = | 48 ++ MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni = | 12 + MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf = | 51 ++ MdeModulePkg/MdeModulePkg.ci.yaml = | 4 +- MdeModulePkg/MdeModulePkg.dec = | 3 + MdeModulePkg/MdeModulePkg.dsc = | 5 + 11 files changed, 1696 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInit= Null.c b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull= .c new file mode 100644 index 000000000000..ad2ee0b2fb8f --- /dev/null +++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitNull.c @@ -0,0 +1,46 @@ +/** @file -- VariablePolicyExtraInitNull.c +This file contains extra init and deinit routines that don't do anything +extra. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + + +/** + An extra init hook that enables the RuntimeDxe library instance to + register VirtualAddress change callbacks. Among other things. + + @retval EFI_SUCCESS Everything is good. Continue with init. + @retval Others Uh... don't continue. + +**/ +EFI_STATUS +VariablePolicyExtraInit ( + VOID + ) +{ + // NULL implementation. + return EFI_SUCCESS; +} + + +/** + An extra deinit hook that enables the RuntimeDxe library instance to + register VirtualAddress change callbacks. Among other things. + + @retval EFI_SUCCESS Everything is good. Continue with deinit. + @retval Others Uh... don't continue. + +**/ +EFI_STATUS +VariablePolicyExtraDeinit ( + VOID + ) +{ + // NULL implementation. + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInit= RuntimeDxe.c b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraIn= itRuntimeDxe.c new file mode 100644 index 000000000000..3ca87048b14b --- /dev/null +++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyExtraInitRuntime= Dxe.c @@ -0,0 +1,85 @@ +/** @file -- VariablePolicyExtraInitRuntimeDxe.c +This file contains extra init and deinit routines that register and unregi= ster +VariableAddressChange callbacks. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +extern EFI_GET_VARIABLE mGetVariableHelper; +extern UINT8 *mPolicyTable; +STATIC BOOLEAN mIsVirtualAddrConverted; +STATIC EFI_EVENT mVariablePolicyLibVirtualAddressChangeEvent =3D= NULL; + +/** + For the RuntimeDxe version of this lib, convert internal pointer address= es to virtual addresses. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context The pointer to the notification function's context= , which + is implementation-dependent. +**/ +STATIC +VOID +EFIAPI +VariablePolicyLibVirtualAddressCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + gRT->ConvertPointer (0, (VOID **)&mPolicyTable); + gRT->ConvertPointer (0, (VOID **)&mGetVariableHelper); + mIsVirtualAddrConverted =3D TRUE; +} + + +/** + An extra init hook that enables the RuntimeDxe library instance to + register VirtualAddress change callbacks. Among other things. + + @retval EFI_SUCCESS Everything is good. Continue with init. + @retval Others Uh... don't continue. + +**/ +EFI_STATUS +VariablePolicyExtraInit ( + VOID + ) +{ + return gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + VariablePolicyLibVirtualAddressCallback, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mVariablePolicyLibVirtualAddressChangeEvent= ); +} + + +/** + An extra deinit hook that enables the RuntimeDxe library instance to + register VirtualAddress change callbacks. Among other things. + + @retval EFI_SUCCESS Everything is good. Continue with deinit. + @retval Others Uh... don't continue. + +**/ +EFI_STATUS +VariablePolicyExtraDeinit ( + VOID + ) +{ + EFI_STATUS Status; + + Status =3D EFI_SUCCESS; + if (mIsVirtualAddrConverted) { + Status =3D gBS->CloseEvent (mVariablePolicyLibVirtualAddressChangeEven= t); + } + else { + Status =3D EFI_SUCCESS; + } + + return Status; +} diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c b/M= deModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c new file mode 100644 index 000000000000..5029ddb96adb --- /dev/null +++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.c @@ -0,0 +1,830 @@ +/** @file -- VariablePolicyLib.c +Business logic for Variable Policy enforcement. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + + +// IMPORTANT NOTE: This library is currently rife with multiple return sta= tements +// for error handling. A refactor should remove these at s= ome point. + +// +// This library was designed with advanced unit-test features. +// This define handles the configuration. +#ifdef INTERNAL_UNIT_TEST +#undef STATIC +#define STATIC // Nothing... +#endif + +// An abstracted GetVariable interface that enables configuration regardle= ss of the environment. +EFI_GET_VARIABLE mGetVariableHelper =3D NULL; + +// Master switch to lock this entire interface. Does not stop enforcement, +// just prevents the configuration from being changed for the rest of the = boot. +STATIC BOOLEAN mInterfaceLocked =3D FALSE; + +// Master switch to disable the entire interface for a single boot. +// This will disable all policy enforcement for the duration of the boot. +STATIC BOOLEAN mProtectionDisabled =3D FALSE; + +// Table to hold all the current policies. +UINT8 *mPolicyTable =3D NULL; +STATIC UINT32 mCurrentTableSize =3D 0; +STATIC UINT32 mCurrentTableUsage =3D 0; +STATIC UINT32 mCurrentTableCount =3D 0; + +#define POLICY_TABLE_STEP_SIZE 0x1000 + +// NOTE: DO NOT USE THESE MACROS on any structure that has not been valida= ted. +// Current table data has already been sanitized. +#define GET_NEXT_POLICY(CurPolicy) (VARIABLE_POLICY_ENTRY*)((UINT8*)Cur= Policy + CurPolicy->Size) +#define GET_POLICY_NAME(CurPolicy) (CHAR16*)((UINTN)CurPolicy + CurPoli= cy->OffsetToName) + +#define MATCH_PRIORITY_EXACT 0 +#define MATCH_PRIORITY_MAX MATCH_PRIORITY_EXACT +#define MATCH_PRIORITY_MIN MAX_UINT8 + + +/** + An extra init hook that enables the RuntimeDxe library instance to + register VirtualAddress change callbacks. Among other things. + + @retval EFI_SUCCESS Everything is good. Continue with init. + @retval Others Uh... don't continue. + +**/ +EFI_STATUS +VariablePolicyExtraInit ( + VOID + ); + +/** + An extra deinit hook that enables the RuntimeDxe library instance to + register VirtualAddress change callbacks. Among other things. + + @retval EFI_SUCCESS Everything is good. Continue with deinit. + @retval Others Uh... don't continue. + +**/ +EFI_STATUS +VariablePolicyExtraDeinit ( + VOID + ); + + +/** + This helper function determines whether the structure of an incoming pol= icy + is valid and internally consistent. + + @param[in] NewPolicy Pointer to the incoming policy structure. + + @retval TRUE + @retval FALSE Pointer is NULL, size is wrong, strings are empty, or + substructures overlap. + +**/ +STATIC +BOOLEAN +IsValidVariablePolicyStructure ( + IN CONST VARIABLE_POLICY_ENTRY *NewPolicy + ) +{ + EFI_STATUS Status; + UINTN EntryEnd; + CHAR16 *CheckChar; + UINTN WildcardCount; + + // Sanitize some quick values. + if (NewPolicy =3D=3D NULL || NewPolicy->Size =3D=3D 0 || + // Structure size should be at least as long as the minumum structur= e and a NULL string. + NewPolicy->Size < sizeof(VARIABLE_POLICY_ENTRY) || + // Check for the known revision. + NewPolicy->Version !=3D VARIABLE_POLICY_ENTRY_REVISION) { + return FALSE; + } + + // Calculate the theoretical end of the structure and make sure + // that the structure can fit in memory. + Status =3D SafeUintnAdd( (UINTN)NewPolicy, NewPolicy->Size, &EntryEnd ); + if (EFI_ERROR( Status )) { + return FALSE; + } + + // Check for a valid Max Size. + if (NewPolicy->MaxSize =3D=3D 0) { + return FALSE; + } + + // Check for the valid list of lock policies. + if (NewPolicy->LockPolicyType !=3D VARIABLE_POLICY_TYPE_NO_LOCK && + NewPolicy->LockPolicyType !=3D VARIABLE_POLICY_TYPE_LOCK_NOW && + NewPolicy->LockPolicyType !=3D VARIABLE_POLICY_TYPE_LOCK_ON_CREATE && + NewPolicy->LockPolicyType !=3D VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STAT= E) + { + return FALSE; + } + + // If the policy type is VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE, make su= re that the matching state variable Name + // terminates before the OffsetToName for the matching policy variable N= ame. + if (NewPolicy->LockPolicyType =3D=3D VARIABLE_POLICY_TYPE_LOCK_ON_VAR_ST= ATE) { + // Adjust CheckChar to the offset of the LockPolicy->Name. + Status =3D SafeUintnAdd( (UINTN)NewPolicy + sizeof(VARIABLE_POLICY_ENT= RY), + sizeof(VARIABLE_LOCK_ON_VAR_STATE_POLICY), + (UINTN*)&CheckChar ); + if (EFI_ERROR( Status ) || EntryEnd <=3D (UINTN)CheckChar) { + return FALSE; + } + while (*CheckChar !=3D CHAR_NULL) { + if (EntryEnd <=3D (UINTN)CheckChar) { + return FALSE; + } + CheckChar++; + } + // At this point we should have either exeeded the structure or be poi= nting at the last char in LockPolicy->Name. + // We should check to make sure that the policy Name comes immediately= after this charcter. + if ((UINTN)++CheckChar !=3D (UINTN)NewPolicy + NewPolicy->OffsetToName= ) { + return FALSE; + } + // If the policy type is any other value, make sure that the LockPolicy = structure has a zero length. + } else { + if (NewPolicy->OffsetToName !=3D sizeof(VARIABLE_POLICY_ENTRY)) { + return FALSE; + } + } + + // Check to make sure that the name has a terminating character + // before the end of the structure. + // We've already checked that the name is within the bounds of the struc= ture. + if (NewPolicy->Size !=3D NewPolicy->OffsetToName) { + CheckChar =3D (CHAR16*)((UINTN)NewPolicy + NewPolicy->OffsetToName); + WildcardCount =3D 0; + while (*CheckChar !=3D CHAR_NULL) { + // Make sure there aren't excessive wildcards. + if (*CheckChar =3D=3D '#') { + WildcardCount++; + if (WildcardCount > MATCH_PRIORITY_MIN) { + return FALSE; + } + } + // Make sure you're still within the bounds of the policy structure. + if (EntryEnd <=3D (UINTN)CheckChar) { + return FALSE; + } + CheckChar++; + } + + // Finally, we should be pointed at the very last character in Name, s= o we should be right + // up against the end of the structure. + if ((UINTN)++CheckChar !=3D EntryEnd) { + return FALSE; + } + } + + return TRUE; +} + + +/** + This helper function evaluates a policy and determines whether it matche= s the target + variable. If matched, will also return a value corresponding to the prio= rity of the match. + + The rules for "best match" are listed in the Variable Policy Spec. + Perfect name matches will return 0. + Single wildcard characters will return the number of wildcard characters. + Full namespaces will return MAX_UINT8. + + @param[in] EvalEntry Pointer to the policy entry being evaluate= d. + @param[in] VariableName Same as EFI_SET_VARIABLE. + @param[in] VendorGuid Same as EFI_SET_VARIABLE. + @param[out] MatchPriority [Optional] On finding a match, this value = contains the priority of the match. + Lower number =3D=3D higher priority. Only = valid if a match found. + + @retval TRUE Current entry matches the target variable. + @retval FALSE Current entry does not match at all. + +**/ +STATIC +BOOLEAN +EvaluatePolicyMatch ( + IN CONST VARIABLE_POLICY_ENTRY *EvalEntry, + IN CONST CHAR16 *VariableName, + IN CONST EFI_GUID *VendorGuid, + OUT UINT8 *MatchPriority OPTIONAL + ) +{ + BOOLEAN Result; + CHAR16 *PolicyName; + UINT8 CalculatedPriority; + UINTN Index; + + Result =3D FALSE; + CalculatedPriority =3D MATCH_PRIORITY_EXACT; + + // Step 1: If the GUID doesn't match, we're done. No need to evaluate an= ything else. + if (!CompareGuid( &EvalEntry->Namespace, VendorGuid )) { + goto Exit; + } + + // If the GUID matches, check to see whether there is a Name associated + // with the policy. If not, this policy matches the entire namespace. + // Missing Name is indicated by size being equal to name. + if (EvalEntry->Size =3D=3D EvalEntry->OffsetToName) { + CalculatedPriority =3D MATCH_PRIORITY_MIN; + Result =3D TRUE; + goto Exit; + } + + // Now that we know the name exists, get it. + PolicyName =3D GET_POLICY_NAME( EvalEntry ); + + // Evaluate the name against the policy name and check for a match. + // Account for any wildcards. + Index =3D 0; + Result =3D TRUE; + // Keep going until the end of both strings. + while (PolicyName[Index] !=3D CHAR_NULL || VariableName[Index] !=3D CHAR= _NULL) { + // If we don't have a match... + if (PolicyName[Index] !=3D VariableName[Index] || PolicyName[Index] = =3D=3D '#') { + // If this is a numerical wildcard, we can consider + // it a match if we alter the priority. + if (PolicyName[Index] =3D=3D L'#' && + ((L'0' <=3D VariableName[Index] && VariableName[Index] <=3D L'= 9') || + (L'A' <=3D VariableName[Index] && VariableName[Index] <=3D L'= F') || + (L'a' <=3D VariableName[Index] && VariableName[Index] <=3D L'= f'))) { + if (CalculatedPriority < MATCH_PRIORITY_MIN) { + CalculatedPriority++; + } + // Otherwise, not a match. + } else { + Result =3D FALSE; + goto Exit; + } + } + Index++; + } + +Exit: + if (Result && MatchPriority !=3D NULL) { + *MatchPriority =3D CalculatedPriority; + } + return Result; +} + + +/** + This helper function walks the current policy table and returns a pointer + to the best match, if any are found. Leverages EvaluatePolicyMatch() to + determine "best". + + @param[in] VariableName Same as EFI_SET_VARIABLE. + @param[in] VendorGuid Same as EFI_SET_VARIABLE. + @param[out] ReturnPriority [Optional] If pointer is provided, return= the + priority of the match. Same as EvaluatePo= licyMatch(). + Only valid if a match is returned. + + @retval VARIABLE_POLICY_ENTRY* Best match that was found. + @retval NULL No match was found. + +**/ +STATIC +VARIABLE_POLICY_ENTRY* +GetBestPolicyMatch ( + IN CONST CHAR16 *VariableName, + IN CONST EFI_GUID *VendorGuid, + OUT UINT8 *ReturnPriority OPTIONAL + ) +{ + VARIABLE_POLICY_ENTRY *BestResult; + VARIABLE_POLICY_ENTRY *CurrentEntry; + UINT8 MatchPriority; + UINT8 CurrentPriority; + UINTN Index; + + BestResult =3D NULL; + MatchPriority =3D MATCH_PRIORITY_EXACT; + + // Walk all entries in the table, looking for matches. + CurrentEntry =3D (VARIABLE_POLICY_ENTRY*)mPolicyTable; + for (Index =3D 0; Index < mCurrentTableCount; Index++) { + // Check for a match. + if (EvaluatePolicyMatch( CurrentEntry, VariableName, VendorGuid, &Curr= entPriority )) { + // If match is better, take it. + if (BestResult =3D=3D NULL || CurrentPriority < MatchPriority) { + BestResult =3D CurrentEntry; + MatchPriority =3D CurrentPriority; + } + + // If you've hit the highest-priority match, can exit now. + if (MatchPriority =3D=3D 0) { + break; + } + } + + // If we're still in the loop, move to the next entry. + CurrentEntry =3D GET_NEXT_POLICY( CurrentEntry ); + } + + // If a return priority was requested, return it. + if (ReturnPriority !=3D NULL) { + *ReturnPriority =3D MatchPriority; + } + + return BestResult; +} + + +/** + This API function validates and registers a new policy with + the policy enforcement engine. + + @param[in] NewPolicy Pointer to the incoming policy structure. + + @retval EFI_SUCCESS + @retval EFI_INVALID_PARAMETER NewPolicy is NULL or is internally i= nconsistent. + @retval EFI_ALREADY_STARTED An identical matching policy already= exists. + @retval EFI_WRITE_PROTECTED The interface has been locked until = the next reboot. + @retval EFI_UNSUPPORTED Policy enforcement has been disabled= . No reason to add more policies. + @retval EFI_ABORTED A calculation error has prevented th= is function from completing. + @retval EFI_OUT_OF_RESOURCES Cannot grow the table to hold any mo= re policies. + @retval EFI_NOT_READY Library has not yet been initialized. + +**/ +EFI_STATUS +EFIAPI +RegisterVariablePolicy ( + IN CONST VARIABLE_POLICY_ENTRY *NewPolicy + ) +{ + EFI_STATUS Status; + VARIABLE_POLICY_ENTRY *MatchPolicy; + UINT8 MatchPriority; + UINT32 NewSize; + UINT8 *NewTable; + + if (!IsVariablePolicyLibInitialized()) { + return EFI_NOT_READY; + } + if (mInterfaceLocked) { + return EFI_WRITE_PROTECTED; + } + + if (!IsValidVariablePolicyStructure( NewPolicy )) { + return EFI_INVALID_PARAMETER; + } + + // Check to see whether an exact matching policy already exists. + MatchPolicy =3D GetBestPolicyMatch( GET_POLICY_NAME( NewPolicy ), + &NewPolicy->Namespace, + &MatchPriority ); + if (MatchPolicy !=3D NULL && MatchPriority =3D=3D MATCH_PRIORITY_EXACT) { + return EFI_ALREADY_STARTED; + } + + // If none exists, create it. + // If we need more space, allocate that now. + Status =3D SafeUint32Add( mCurrentTableUsage, NewPolicy->Size, &NewSize = ); + if (EFI_ERROR( Status )) { + return EFI_ABORTED; + } + if (NewSize > mCurrentTableSize) { + // Use NewSize to calculate the new table size in units of POLICY_TABL= E_STEP_SIZE. + NewSize =3D (NewSize % POLICY_TABLE_STEP_SIZE) > 0 ? + (NewSize / POLICY_TABLE_STEP_SIZE) + 1 : + (NewSize / POLICY_TABLE_STEP_SIZE); + // Calculate the new table size in absolute bytes. + Status =3D SafeUint32Mult( NewSize, POLICY_TABLE_STEP_SIZE, &NewSize ); + if (EFI_ERROR( Status )) { + return EFI_ABORTED; + } + + // Reallocate and copy the table. + NewTable =3D AllocatePool( NewSize ); + if (NewTable =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem( NewTable, mPolicyTable, mCurrentTableUsage ); + mCurrentTableSize =3D NewSize; + if (mPolicyTable !=3D NULL) { + FreePool( mPolicyTable ); + } + mPolicyTable =3D NewTable; + } + // Copy the policy into the table. + CopyMem( mPolicyTable + mCurrentTableUsage, NewPolicy, NewPolicy->Size ); + mCurrentTableUsage +=3D NewPolicy->Size; + mCurrentTableCount +=3D 1; + + // We're done here. + + return EFI_SUCCESS; +} + + +/** + This API function checks to see whether the parameters to SetVariable wo= uld + be allowed according to the current variable policies. + + @param[in] VariableName Same as EFI_SET_VARIABLE. + @param[in] VendorGuid Same as EFI_SET_VARIABLE. + @param[in] Attributes Same as EFI_SET_VARIABLE. + @param[in] DataSize Same as EFI_SET_VARIABLE. + @param[in] Data Same as EFI_SET_VARIABLE. + + @retval EFI_SUCCESS A matching policy allows this update. + @retval EFI_SUCCESS There are currently no policies that= restrict this update. + @retval EFI_SUCCESS The protections have been disable un= til the next reboot. + @retval EFI_WRITE_PROTECTED Variable is currently locked. + @retval EFI_INVALID_PARAMETER Attributes or size are invalid. + @retval EFI_ABORTED A lock policy exists, but an error p= revented evaluation. + @retval EFI_NOT_READY Library has not been initialized. + +**/ +EFI_STATUS +EFIAPI +ValidateSetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + BOOLEAN IsDel; + VARIABLE_POLICY_ENTRY *ActivePolicy; + EFI_STATUS Status; + EFI_STATUS ReturnStatus; + VARIABLE_LOCK_ON_VAR_STATE_POLICY *StateVarPolicy; + CHAR16 *StateVarName; + UINTN StateVarSize; + UINT8 StateVar; + + ReturnStatus =3D EFI_SUCCESS; + + if (!IsVariablePolicyLibInitialized()) { + ReturnStatus =3D EFI_NOT_READY; + goto Exit; + } + + // Bail if the protections are currently disabled. + if (mProtectionDisabled) { + ReturnStatus =3D EFI_SUCCESS; + goto Exit; + } + + // Determine whether this is a delete operation. + // If so, it will affect which tests are applied. + if ((DataSize =3D=3D 0) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) =3D= =3D 0)) { + IsDel =3D TRUE; + } else { + IsDel =3D FALSE; + } + + // Find an active policy if one exists. + ActivePolicy =3D GetBestPolicyMatch( VariableName, VendorGuid, NULL ); + + // If we have an active policy, check it against the incoming data. + if (ActivePolicy !=3D NULL) { + // + // Only enforce size and attribute constraints when updating data, not= deleting. + if (!IsDel) { + // Check for size constraints. + if ((ActivePolicy->MinSize > 0 && DataSize < ActivePolicy->MinSize) = || + (ActivePolicy->MaxSize > 0 && DataSize > ActivePolicy->MaxSize))= { + ReturnStatus =3D EFI_INVALID_PARAMETER; + DEBUG(( DEBUG_VERBOSE, "%a - Bad Size. 0x%X <> 0x%X-0x%X\n", __FUN= CTION__, + DataSize, ActivePolicy->MinSize, ActivePolicy->MaxSize )); + goto Exit; + } + + // Check for attribute constraints. + if ((ActivePolicy->AttributesMustHave & Attributes) !=3D ActivePolic= y->AttributesMustHave || + (ActivePolicy->AttributesCantHave & Attributes) !=3D 0) { + ReturnStatus =3D EFI_INVALID_PARAMETER; + DEBUG(( DEBUG_VERBOSE, "%a - Bad Attributes. 0x%X <> 0x%X:0x%X\n",= __FUNCTION__, + Attributes, ActivePolicy->AttributesMustHave, ActivePolicy= ->AttributesCantHave )); + goto Exit; + } + } + + // + // Lock policy check. + // + // Check for immediate lock. + if (ActivePolicy->LockPolicyType =3D=3D VARIABLE_POLICY_TYPE_LOCK_NOW)= { + ReturnStatus =3D EFI_WRITE_PROTECTED; + goto Exit; + // Check for lock on create. + } else if (ActivePolicy->LockPolicyType =3D=3D VARIABLE_POLICY_TYPE_LO= CK_ON_CREATE) { + StateVarSize =3D 0; + Status =3D mGetVariableHelper( VariableName, + VendorGuid, + NULL, + &StateVarSize, + NULL ); + if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { + ReturnStatus =3D EFI_WRITE_PROTECTED; + goto Exit; + } + // Check for lock on state variable. + } else if (ActivePolicy->LockPolicyType =3D=3D VARIABLE_POLICY_TYPE_LO= CK_ON_VAR_STATE) { + StateVarPolicy =3D (VARIABLE_LOCK_ON_VAR_STATE_POLICY*)((UINT8*)Acti= vePolicy + sizeof(VARIABLE_POLICY_ENTRY)); + StateVarName =3D (CHAR16*)((UINT8*)StateVarPolicy + sizeof(VARIABLE_= LOCK_ON_VAR_STATE_POLICY)); + StateVarSize =3D sizeof(StateVar); + Status =3D mGetVariableHelper( StateVarName, + &StateVarPolicy->Namespace, + NULL, + &StateVarSize, + &StateVar ); + + // If the variable was found, check the state. If matched, this vari= able is locked. + if (!EFI_ERROR( Status )) { + if (StateVar =3D=3D StateVarPolicy->Value) { + ReturnStatus =3D EFI_WRITE_PROTECTED; + goto Exit; + } + // EFI_NOT_FOUND and EFI_BUFFER_TOO_SMALL indicate that the state do= esn't match. + } else if (Status !=3D EFI_NOT_FOUND && Status !=3D EFI_BUFFER_TOO_S= MALL) { + // We don't know what happened, but it isn't good. + ReturnStatus =3D EFI_ABORTED; + goto Exit; + } + } + } + +Exit: + DEBUG(( DEBUG_VERBOSE, "%a - Variable (%g:%s) returning %r.\n", __FUNCTI= ON__, VendorGuid, VariableName, ReturnStatus )); + return ReturnStatus; +} + + +/** + This API function disables the variable policy enforcement. If it's + already been called once, will return EFI_ALREADY_STARTED. + + @retval EFI_SUCCESS + @retval EFI_ALREADY_STARTED Has already been called once this boot. + @retval EFI_WRITE_PROTECTED Interface has been locked until reboot. + @retval EFI_WRITE_PROTECTED Interface option is disabled by platfo= rm PCD. + @retval EFI_NOT_READY Library has not yet been initialized. + +**/ +EFI_STATUS +EFIAPI +DisableVariablePolicy ( + VOID + ) +{ + if (!IsVariablePolicyLibInitialized()) { + return EFI_NOT_READY; + } + if (mProtectionDisabled) { + return EFI_ALREADY_STARTED; + } + if (mInterfaceLocked) { + return EFI_WRITE_PROTECTED; + } + if (!PcdGetBool (PcdAllowVariablePolicyEnforcementDisable)) { + return EFI_WRITE_PROTECTED; + } + mProtectionDisabled =3D TRUE; + return EFI_SUCCESS; +} + + +/** + This API function will dump the entire contents of the variable policy t= able. + + Similar to GetVariable, the first call can be made with a 0 size and it = will return + the size of the buffer required to hold the entire table. + + @param[out] Policy Pointer to the policy buffer. Can be NULL if Siz= e is 0. + @param[in,out] Size On input, the size of the output buffer. On outp= ut, the size + of the data returned. + + @retval EFI_SUCCESS Policy data is in the output buffer = and Size has been updated. + @retval EFI_INVALID_PARAMETER Size is NULL, or Size is non-zero an= d Policy is NULL. + @retval EFI_BUFFER_TOO_SMALL Size is insufficient to hold policy.= Size updated with required size. + @retval EFI_NOT_READY Library has not yet been initialized. + +**/ +EFI_STATUS +EFIAPI +DumpVariablePolicy ( + OUT UINT8 *Policy, + IN OUT UINT32 *Size + ) +{ + if (!IsVariablePolicyLibInitialized()) { + return EFI_NOT_READY; + } + + // Check the parameters. + if (Size =3D=3D NULL || (*Size > 0 && Policy =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + // Make sure the size is sufficient to hold the policy table. + if (*Size < mCurrentTableUsage) { + *Size =3D mCurrentTableUsage; + return EFI_BUFFER_TOO_SMALL; + } + + // If we're still here, copy the table and bounce. + CopyMem( Policy, mPolicyTable, mCurrentTableUsage ); + *Size =3D mCurrentTableUsage; + + return EFI_SUCCESS; +} + + +/** + This API function returns whether or not the policy engine is + currently being enforced. + + @retval TRUE + @retval FALSE + @retval FALSE Library has not yet been initialized. + +**/ +BOOLEAN +EFIAPI +IsVariablePolicyEnabled ( + VOID + ) +{ + if (!IsVariablePolicyLibInitialized()) { + return FALSE; + } + return !mProtectionDisabled; +} + + +/** + This API function locks the interface so that no more policy updates + can be performed or changes made to the enforcement until the next boot. + + @retval EFI_SUCCESS + @retval EFI_NOT_READY Library has not yet been initialized. + +**/ +EFI_STATUS +EFIAPI +LockVariablePolicy ( + VOID + ) +{ + if (!IsVariablePolicyLibInitialized()) { + return EFI_NOT_READY; + } + if (mInterfaceLocked) { + return EFI_WRITE_PROTECTED; + } + mInterfaceLocked =3D TRUE; + return EFI_SUCCESS; +} + + +/** + This API function returns whether or not the policy interface is locked + for the remainder of the boot. + + @retval TRUE + @retval FALSE + @retval FALSE Library has not yet been initialized. + +**/ +BOOLEAN +EFIAPI +IsVariablePolicyInterfaceLocked ( + VOID + ) +{ + if (!IsVariablePolicyLibInitialized()) { + return FALSE; + } + return mInterfaceLocked; +} + + +/** + This helper function initializes the library and sets + up any required internal structures or handlers. + + Also registers the internal pointer for the GetVariable helper. + + @param[in] GetVariableHelper A function pointer matching the EFI_GET_VA= RIABLE prototype that will be used to + check policy criteria that involve the existence of othe= r variables. + + @retval EFI_SUCCESS + @retval EFI_ALREADY_STARTED The initialize function has been calle= d more than once without a call to + deinitialize. + +**/ +EFI_STATUS +EFIAPI +InitVariablePolicyLib ( + IN EFI_GET_VARIABLE GetVariableHelper + ) +{ + EFI_STATUS Status; + + Status =3D EFI_SUCCESS; + + if (mGetVariableHelper !=3D NULL) { + return EFI_ALREADY_STARTED; + } + + if (!EFI_ERROR( Status )) { + Status =3D VariablePolicyExtraInit(); + } + + if (!EFI_ERROR( Status )) { + // Save an internal pointer to the GetVariableHelper. + mGetVariableHelper =3D GetVariableHelper; + + // Initialize the global state. + mInterfaceLocked =3D FALSE; + mProtectionDisabled =3D FALSE; + mPolicyTable =3D NULL; + mCurrentTableSize =3D 0; + mCurrentTableUsage =3D 0; + mCurrentTableCount =3D 0; + } + + return Status; +} + + +/** + This helper function returns whether or not the library is currently ini= tialized. + + @retval TRUE + @retval FALSE + +**/ +BOOLEAN +EFIAPI +IsVariablePolicyLibInitialized ( + VOID + ) +{ + return (mGetVariableHelper !=3D NULL); +} + + +/** + This helper function tears down the library. + + Should generally only be used for test harnesses. + + @retval EFI_SUCCESS + @retval EFI_NOT_READY Deinitialize was called without first call= ing initialize. + +**/ +EFI_STATUS +EFIAPI +DeinitVariablePolicyLib ( + VOID + ) +{ + EFI_STATUS Status; + + Status =3D EFI_SUCCESS; + + if (mGetVariableHelper =3D=3D NULL) { + return EFI_NOT_READY; + } + + if (!EFI_ERROR( Status )) { + Status =3D VariablePolicyExtraDeinit(); + } + + if (!EFI_ERROR( Status )) { + mGetVariableHelper =3D NULL; + mInterfaceLocked =3D FALSE; + mProtectionDisabled =3D FALSE; + mCurrentTableSize =3D 0; + mCurrentTableUsage =3D 0; + mCurrentTableCount =3D 0; + + if (mPolicyTable !=3D NULL) { + FreePool( mPolicyTable ); + mPolicyTable =3D NULL; + } + } + + return Status; +} diff --git a/MdeModulePkg/Include/Library/VariablePolicyLib.h b/MdeModulePk= g/Include/Library/VariablePolicyLib.h new file mode 100644 index 000000000000..efd1840112ec --- /dev/null +++ b/MdeModulePkg/Include/Library/VariablePolicyLib.h @@ -0,0 +1,207 @@ +/** @file -- VariablePolicyLib.h +Business logic for Variable Policy enforcement. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _VARIABLE_POLICY_LIB_H_ +#define _VARIABLE_POLICY_LIB_H_ + +#include + +/** + This API function validates and registers a new policy with + the policy enforcement engine. + + @param[in] NewPolicy Pointer to the incoming policy structure. + + @retval EFI_SUCCESS + @retval EFI_INVALID_PARAMETER NewPolicy is NULL or is internally i= nconsistent. + @retval EFI_ALREADY_STARTED An identical matching policy already= exists. + @retval EFI_WRITE_PROTECTED The interface has been locked until = the next reboot. + @retval EFI_UNSUPPORTED Policy enforcement has been disabled= . No reason to add more policies. + @retval EFI_ABORTED A calculation error has prevented th= is function from completing. + @retval EFI_OUT_OF_RESOURCES Cannot grow the table to hold any mo= re policies. + @retval EFI_NOT_READY Library has not yet been initialized. + +**/ +EFI_STATUS +EFIAPI +RegisterVariablePolicy ( + IN CONST VARIABLE_POLICY_ENTRY *NewPolicy + ); + + +/** + This API function checks to see whether the parameters to SetVariable wo= uld + be allowed according to the current variable policies. + + @param[in] VariableName Same as EFI_SET_VARIABLE. + @param[in] VendorGuid Same as EFI_SET_VARIABLE. + @param[in] Attributes Same as EFI_SET_VARIABLE. + @param[in] DataSize Same as EFI_SET_VARIABLE. + @param[in] Data Same as EFI_SET_VARIABLE. + + @retval EFI_SUCCESS A matching policy allows this update. + @retval EFI_SUCCESS There are currently no policies that= restrict this update. + @retval EFI_SUCCESS The protections have been disable un= til the next reboot. + @retval EFI_WRITE_PROTECTED Variable is currently locked. + @retval EFI_INVALID_PARAMETER Attributes or size are invalid. + @retval EFI_ABORTED A lock policy exists, but an error p= revented evaluation. + @retval EFI_NOT_READY Library has not been initialized. + +**/ +EFI_STATUS +EFIAPI +ValidateSetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ); + + +/** + This API function disables the variable policy enforcement. If it's + already been called once, will return EFI_ALREADY_STARTED. + + @retval EFI_SUCCESS + @retval EFI_ALREADY_STARTED Has already been called once this boot. + @retval EFI_WRITE_PROTECTED Interface has been locked until reboot. + @retval EFI_WRITE_PROTECTED Interface option is disabled by platfo= rm PCD. + @retval EFI_NOT_READY Library has not yet been initialized. + +**/ +EFI_STATUS +EFIAPI +DisableVariablePolicy ( + VOID + ); + + +/** + This API function will dump the entire contents of the variable policy t= able. + + Similar to GetVariable, the first call can be made with a 0 size and it = will return + the size of the buffer required to hold the entire table. + + @param[out] Policy Pointer to the policy buffer. Can be NULL if Siz= e is 0. + @param[in,out] Size On input, the size of the output buffer. On outp= ut, the size + of the data returned. + + @retval EFI_SUCCESS Policy data is in the output buffer = and Size has been updated. + @retval EFI_INVALID_PARAMETER Size is NULL, or Size is non-zero an= d Policy is NULL. + @retval EFI_BUFFER_TOO_SMALL Size is insufficient to hold policy.= Size updated with required size. + @retval EFI_NOT_READY Library has not yet been initialized. + +**/ +EFI_STATUS +EFIAPI +DumpVariablePolicy ( + OUT UINT8 *Policy, + IN OUT UINT32 *Size + ); + + +/** + This API function returns whether or not the policy engine is + currently being enforced. + + @retval TRUE + @retval FALSE + @retval FALSE Library has not yet been initialized. + +**/ +BOOLEAN +EFIAPI +IsVariablePolicyEnabled ( + VOID + ); + + +/** + This API function locks the interface so that no more policy updates + can be performed or changes made to the enforcement until the next boot. + + @retval EFI_SUCCESS + @retval EFI_NOT_READY Library has not yet been initialized. + +**/ +EFI_STATUS +EFIAPI +LockVariablePolicy ( + VOID + ); + + +/** + This API function returns whether or not the policy interface is locked + for the remainder of the boot. + + @retval TRUE + @retval FALSE + @retval FALSE Library has not yet been initialized. + +**/ +BOOLEAN +EFIAPI +IsVariablePolicyInterfaceLocked ( + VOID + ); + + +/** + This helper function initializes the library and sets + up any required internal structures or handlers. + + Also registers the internal pointer for the GetVariable helper. + + @param[in] GetVariableHelper A function pointer matching the EFI_GET_VA= RIABLE prototype that will be used to + check policy criteria that involve the existence of othe= r variables. + + @retval EFI_SUCCESS + @retval EFI_ALREADY_STARTED The initialize function has been calle= d more than once without a call to + deinitialize. + +**/ +EFI_STATUS +EFIAPI +InitVariablePolicyLib ( + IN EFI_GET_VARIABLE GetVariableHelper + ); + + +/** + This helper function returns whether or not the library is currently ini= tialized. + + @retval TRUE + @retval FALSE + +**/ +BOOLEAN +EFIAPI +IsVariablePolicyLibInitialized ( + VOID + ); + + +/** + This helper function tears down the library. + + Should generally only be used for test harnesses. + + @retval EFI_SUCCESS + @retval EFI_NOT_READY Deinitialize was called without first call= ing initialize. + +**/ +EFI_STATUS +EFIAPI +DeinitVariablePolicyLib ( + VOID + ); + + +#endif // _VARIABLE_POLICY_LIB_H_ diff --git a/MdeModulePkg/Library/VariablePolicyLib/ReadMe.md b/MdeModulePk= g/Library/VariablePolicyLib/ReadMe.md new file mode 100644 index 000000000000..c2f9850a12ca --- /dev/null +++ b/MdeModulePkg/Library/VariablePolicyLib/ReadMe.md @@ -0,0 +1,406 @@ +--- +title: UEFI Variable Policy Whitepaper +version: 1.0 +copyright: Copyright (c) Microsoft Corporation. +--- + +# UEFI Variable Policy + +## Summary + +UEFI Variable Policy spec aims to describe the DXE protocol interface +which allows enforcing certain rules on certain UEFI variables. The +protocol allows communication with the Variable Policy Engine which +performs the policy enforcement. + +The Variable Policy is comprised of a set of policy entries which +describe, per UEFI variable (identified by namespace GUID and variable +name) the following rules: + +- Required variable attributes +- Prohibited variable attributes +- Minimum variable size +- Maximum variable size +- Locking: + - Locking "immediately" + - Locking on creation + - Locking based on a state of another variable + +The spec assumes that the Variable Policy Engine runs in a trusted +enclave, potentially off the main CPU that runs UEFI. For that reason, +it is assumed that the Variable Policy Engine has no concept of UEFI +events, and that the communication from the DXE driver to the trusted +enclave is proprietary. + +At power-on, the Variable Policy Engine is: + +- Enabled -- present policy entries are evaluated on variable access + calls. +- Unlocked -- new policy entries can be registered. + +Policy is expected to be clear on power-on. Policy is volatile and not +preserved across system reset. + +## DXE Protocol + +```h +typedef struct { + UINT64 Revision; + DISABLE_VARIABLE_POLICY DisableVariablePolicy; + IS_VARIABLE_POLICY_ENABLED IsVariablePolicyEnabled; + REGISTER_VARIABLE_POLICY RegisterVariablePolicy; + DUMP_VARIABLE_POLICY DumpVariablePolicy; + LOCK_VARIABLE_POLICY LockVariablePolicy; +} _VARIABLE_POLICY_PROTOCOL; + +typedef _VARIABLE_POLICY_PROTOCOL VARIABLE_POLICY_PROTOCOL; + +extern EFI_GUID gVariablePolicyProtocolGuid; +``` + +```text +## Include/Protocol/VariablePolicy.h + gVariablePolicyProtocolGuid =3D { 0x81D1675C, 0x86F6, 0x48DF, { 0xBD, 0x= 95, 0x9A, 0x6E, 0x4F, 0x09, 0x25, 0xC3 } } +``` + +### DisableVariablePolicy + +Function prototype: + +```c +EFI_STATUS +EFIAPI +DisableVariablePolicy ( + VOID + ); +``` + +`DisableVariablePolicy` call disables the Variable Policy Engine, so +that the present policy entries are no longer taken into account on +variable access calls. This call effectively turns off the variable +policy verification for this boot. This also disables UEFI +Authenticated Variable protections including Secure Boot. +`DisableVariablePolicy` can only be called once during boot. If called +more than once, it will return `EFI_ALREADY_STARTED`. Note, this process +is irreversible until the next system reset -- there is no +"EnablePolicy" protocol function. + +_IMPORTANT NOTE:_ It is strongly recommended that VariablePolicy *NEVER* +be disabled in "normal, production boot conditions". It is expected to alw= ays +be enforced. The most likely reasons to disable are for Manufacturing and +Refurbishing scenarios. If in doubt, leave the `gEfiMdeModulePkgTokenSpace= Guid.PcdAllowVariablePolicyEnforcementDisable` +PCD set to `FALSE` and VariablePolicy will always be enabled. + +### IsVariablePolicyEnabled + +Function prototype: + +```c +EFI_STATUS +EFIAPI +IsVariablePolicyEnabled ( + OUT BOOLEAN *State + ); +``` + +`IsVariablePolicyEnabled` accepts a pointer to a Boolean in which it +will store `TRUE` if Variable Policy Engine is enabled, or `FALSE` if +Variable Policy Engine is disabled. The function returns `EFI_SUCCESS`. + +### RegisterVariablePolicy + +Function prototype: + +```c +EFI_STATUS +EFIAPI +RegisterVariablePolicy ( + IN CONST VARIABLE_POLICY_ENTRY *PolicyEntry + ); +``` + +`RegisterVariablePolicy` call accepts a pointer to a policy entry +structure and returns the status of policy registration. If the +Variable Policy Engine is not locked and the policy structures are +valid, the function will return `EFI_SUCCESS`. If the Variable Policy +Engine is locked, `RegisterVariablePolicy` call will return +`EFI_WRITE_PROTECTED` and will not register the policy entry. Bulk +registration is not supported at this time due to the requirements +around error handling on each policy registration. + +Upon successful registration of a policy entry, Variable Policy Engine +will then evaluate this entry on subsequent variable access calls (as +long as Variable Policy Engine hasn't been disabled). + +### DumpVariablePolicy + +Function prototype: + +```c +EFI_STATUS +EFIAPI +DumpVariablePolicy ( + OUT UINT8 *Policy, + IN OUT UINT32 *Size + ); +``` + +`DumpVariablePolicy` call accepts a pointer to a buffer and a pointer to +the size of the buffer as parameters and returns the status of placing +the policy into the buffer. On first call to `DumpVariablePolicy` one +should pass `NULL` as the buffer and a pointer to 0 as the `Size` variable +and `DumpVariablePolicy` will return `EFI_BUFFER_TOO_SMALL` and will +populate the `Size` parameter with the size of the needed buffer to +store the policy. This way, the caller can allocate the buffer of +correct size and call `DumpVariablePolicy` again. The function will +populate the buffer with policy and return `EFI_SUCCESS`. + +### LockVariablePolicy + +Function prototype: + +```c +EFI_STATUS +EFIAPI +LockVariablePolicy ( + VOID + ); +``` + +`LockVariablePolicy` locks the Variable Policy Engine, i.e. prevents any +new policy entries from getting registered in this boot +(`RegisterVariablePolicy` calls will fail with `EFI_WRITE_PROTECTED` +status code returned). + +## Policy Structure + +The structure below is meant for the DXE protocol calling interface, +when communicating to the Variable Policy Engine, thus the pragma pack +directive. How these policies are stored in memory is up to the +implementation. + +```c +#pragma pack(1) +typedef struct { + UINT32 Version; + UINT16 Size; + UINT16 OffsetToName; + EFI_GUID Namespace; + UINT32 MinSize; + UINT32 MaxSize; + UINT32 AttributesMustHave; + UINT32 AttributesCantHave; + UINT8 LockPolicyType; + UINT8 Reserved[3]; + // UINT8 LockPolicy[]; // Variable Length Field + // CHAR16 Name[]; // Variable Length Field +} VARIABLE_POLICY_ENTRY; +``` + +The struct `VARIABLE_POLICY_ENTRY` above describes the layout for a policy +entry. The first element, `Size`, is the size of the policy entry, then +followed by `OffsetToName` -- the number of bytes from the beginning of +the struct to the name of the UEFI variable targeted by the policy +entry. The name can contain wildcards to match more than one variable, +more on this in the Wildcards section. The rest of the struct elements +are self-explanatory. + +```cpp +#define VARIABLE_POLICY_TYPE_NO_LOCK 0 +#define VARIABLE_POLICY_TYPE_LOCK_NOW 1 +#define VARIABLE_POLICY_TYPE_LOCK_ON_CREATE 2 +#define VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE 3 +``` + +`LockPolicyType` can have the following values: + +- `VARIABLE_POLICY_TYPE_NO_LOCK` -- means that no variable locking is pe= rformed. However, + the attribute and size constraints are still enforced. LockPolicy + field is size 0. +- `VARIABLE_POLICY_TYPE_LOCK_NOW` -- means that the variable starts bein= g locked + immediately after policy entry registration. If the variable doesn't + exist at this point, being LockedNow means it cannot be created on + this boot. LockPolicy field is size 0. +- `VARIABLE_POLICY_TYPE_LOCK_ON_CREATE` -- means that the variable start= s being locked + after it is created. This allows for variable creation and + protection after LockVariablePolicy() function has been called. The + LockPolicy field is size 0. +- `VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE` -- means that the Variable Po= licy Engine will + examine the state/contents of another variable to determine if the + variable referenced in the policy entry is locked. + +```c +typedef struct { + EFI_GUID Namespace; + UINT8 Value; + UINT8 Reserved; + // CHAR16 Name[]; // Variable Length Field +} VARIABLE_LOCK_ON_VAR_STATE_POLICY; +``` + +If `LockPolicyType` is `VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE`, then the = final element in the +policy entry struct is of type `VARIABLE_LOCK_ON_VAR_STATE_POLICY`, which +lists the namespace GUID, name (no wildcards here), and value of the +variable which state determines the locking of the variable referenced +in the policy entry. The "locking" variable must be 1 byte in terms of +payload size. If the Referenced variable contents match the Value of the +`VARIABLE_LOCK_ON_VAR_STATE_POLICY` structure, the lock will be considered +active and the target variable will be locked. If the Reference variable +does not exist (ie. returns `EFI_NOT_FOUND`), this policy will be +considered inactive. + +## Variable Name Wildcards + +Two types of wildcards can be used in the UEFI variable name field in a +policy entry: + +1. If the Name is a zero-length array (easily checked by comparing + fields `Size` and `OffsetToName` -- if they're the same, then the + `Name` is zero-length), then all variables in the namespace specified + by the provided GUID are targeted by the policy entry. +2. Character "#" in the `Name` corresponds to one numeric character + (0-9, A-F, a-f). For example, string "Boot####" in the `Name` + field of the policy entry will make it so that the policy entry will + target variables named "Boot0001", "Boot0002", etc. + +Given the above two types of wildcards, one variable can be targeted by +more than one policy entry, thus there is a need to establish the +precedence rule: a more specific match is applied. When a variable +access operation is performed, Variable Policy Engine should first check +the variable being accessed against the policy entries without +wildcards, then with 1 wildcard, then with 2 wildcards, etc., followed +in the end by policy entries that match the whole namespace. One can +still imagine a situation where two policy entries with the same number +of wildcards match the same variable -- for example, policy entries with +Names "Boot00##" and "Boot##01" will both match variable "Boot0001". +Such situation can (and should) be avoided by designing mutually +exclusive Name strings with wildcards, however, if it occurs, then the +policy entry that was registered first will be used. After the most +specific match is selected, all other policies are ignored. + +## Available Testing + +This functionality is current supported by two kinds of tests: there is a = host-based +unit test for the core business logic (this test accompanies the `Variable= PolicyLib` +implementation that lives in `MdeModulePkg/Library`) and there is a functi= onal test +for the protocol and its interfaces (this test lives in the `MdeModulePkg/= Test/ShellTest` +directory). + +### Host-Based Unit Test + +There is a test that can be run as part of the Host-Based Unit Testing +infrastructure provided by EDK2 PyTools (documented elsewhere). It will te= st +all internal guarantees and is where you will find test cases for most of = the +policy matching and security of the Variable Policy Engine. + +### Shell-Based Functional Test + +This test -- [Variable Policy Functional Unit Test](https://github.com/mic= rosoft/mu_plus/tree/release/202005/UefiTestingPkg/FunctionalSystemTests/Var= PolicyUnitTestApp) -- can be built as a +UEFI Shell application and run to validate that the Variable Policy Engine +is correctly installed and enforcing policies on the target system. + +NOTE: This test _must_ be run prior to calling `DisableVariablePolicy` for= all +test cases to pass. For this reason, it is recommended to run this on a te= st-built +FW for complete results, and then again on a production-built FW for relea= se +results. + +## Use Cases + +The below examples are hypothetical scenarios based on real-world requirem= ents +that demonstrate how Variable Policies could be constructed to solve vario= us +problems. + +### UEFI Setup Variables (Example 1) + +Variables containing values of the setup options exposed via UEFI +menu (setup variables). These would be locked based on a state of +another variable, "ReadyToBoot", which would be set to 1 at the +ReadyToBoot event. Thus, the policy for the setup variables would be +of type `LockOnVarState`, with the "ReadyToBoot" listed as the name of +the variable, appropriate GUID listed as the namespace, and 1 as +value. Entry into the trusted UEFI menu app doesn't signal +ReadyToBoot, but booting to any device does, and the setup variables +are write-protected. The "ReadyToBoot" variable would need to be +locked-on-create. *(THIS IS ESSENTIALLY LOCK ON EVENT, BUT SINCE THE +POLICY ENGINE IS NOT IN THE UEFI ENVIRONMENT VARIABLES ARE USED)* + +For example, "AllowPXEBoot" variable locked by "ReadyToBoot" variable. + +(NOTE: In the below example, the emphasized fields ('Namespace', 'Value', = and 'Name') +are members of the `VARIABLE_LOCK_ON_VAR_STATE_POLICY` structure.) + +Size | ... +---- | --- +OffsetToName | ... +NameSpace | ... +MinSize | ... +MaxSize | ... +AttributesMustHave | ... +AttributesCantHave | ... +LockPolicyType | `VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE` +_Namespace_ | ... +_Value_ | 1 +_Name_ | "ReadyToBoot" +//Name | "AllowPXEBoot" + +### Manufacturing VPD (Example 2) + +Manufacturing Variable Provisioning Data (VPD) is stored in +variables and is created while in Manufacturing (MFG) Mode. In MFG +Mode Variable Policy Engine is disabled, thus these VPD variables +can be created. These variables are locked with lock policy type +`LockNow`, so that these variables can't be tampered with in Customer +Mode. To overwrite or clear VPD, the device would need to MFG mode, +which is standard practice for refurbishing/remanufacturing +scenarios. + +Example: "DisplayPanelCalibration" variable... + +Size | ... +---- | --- +OffsetToName | ... +NameSpace | ... +MinSize | ... +MaxSize | ... +AttributesMustHave | ... +AttributesCantHave | ... +LockPolicyType | `VARIABLE_POLICY_TYPE_LOCK_NOW` +// Name | "DisplayPanelCalibration" + +### 3rd Party Calibration Data (Example 3) + +Bluetooth pre-pairing variables are locked-on-create because these +get created by an OS application when Variable Policy is in effect. + +Example: "KeyboardBTPairing" variable + +Size | ... +---- | --- +OffsetToName | ... +NameSpace | ... +MinSize | ... +MaxSize | ... +AttributesMustHave | ... +AttributesCantHave | ... +LockPolicyType | `VARIABLE_POLICY_TYPE_LOCK_ON_CREATE` +// Name | "KeyboardBTPairing" + +### Software-based Variable Policy (Example 4) + +Example: "Boot####" variables (a name string with wildcards that +will match variables "Boot0000" to "BootFFFF") locked by "LockBootOrder" +variable. + +Size | ... +---- | --- +OffsetToName | ... +NameSpace | ... +MinSize | ... +MaxSize | ... +AttributesMustHave | ... +AttributesCantHave | ... +LockPolicyType | `VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE` +_Namespace_ | ... +_Value_ | 1 +_Name_ | "LockBootOrder" +//Name | "Boot####" diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf b= /MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf new file mode 100644 index 000000000000..3fe6043bf631 --- /dev/null +++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf @@ -0,0 +1,48 @@ +## @file VariablePolicyLib.inf +# Business logic for Variable Policy enforcement. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D VariablePolicyLib + FILE_GUID =3D E9ECD342-159A-4F24-9FDF-65724027C594 + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_DRIVER + LIBRARY_CLASS =3D VariablePolicyLib|DXE_DRIVER DXE_SMM_DRIVER MM_S= TANDALONE + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D ANY +# + + +[Sources] + VariablePolicyLib.c + VariablePolicyExtraInitNull.c + + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +[LibraryClasses] + DebugLib + BaseMemoryLib + MemoryAllocationLib + SafeIntLib + PcdLib + + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDisable = ## CONSUMES + + +[BuildOptions] + MSFT:NOOPT_*_*_CC_FLAGS =3D -DINTERNAL_UNIT_TEST + GCC:NOOPT_*_*_CC_FLAGS =3D -DINTERNAL_UNIT_TEST diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni b= /MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni new file mode 100644 index 000000000000..2227ec427828 --- /dev/null +++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.uni @@ -0,0 +1,12 @@ +// /** @file +// VariablePolicyLib.uni +// +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Library containin= g the business logic for the VariablePolicy engine" + +#string STR_MODULE_DESCRIPTION #language en-US "Library containin= g the business logic for the VariablePolicy engine" diff --git a/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntim= eDxe.inf b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeD= xe.inf new file mode 100644 index 000000000000..8b8365741864 --- /dev/null +++ b/MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf @@ -0,0 +1,51 @@ +## @file VariablePolicyLibRuntimeDxe.inf +# Business logic for Variable Policy enforcement. +# This instance is specifically for RuntimeDxe and contains +# extra routines to register for VirtualAddressChangeEvents. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D VariablePolicyLibRuntimeDxe + FILE_GUID =3D 205F7F0E-8EAC-4914-8390-1B90DD7E2A27 + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_RUNTIME_DRIVER + LIBRARY_CLASS =3D VariablePolicyLib|DXE_RUNTIME_DRIVER + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D ANY +# + + +[Sources] + VariablePolicyLib.c + VariablePolicyExtraInitRuntimeDxe.c + + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +[LibraryClasses] + DebugLib + BaseMemoryLib + MemoryAllocationLib + SafeIntLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + PcdLib + + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDisable = ## CONSUMES + + +[Guids] + gEfiEventVirtualAddressChangeGuid diff --git a/MdeModulePkg/MdeModulePkg.ci.yaml b/MdeModulePkg/MdeModulePkg.= ci.yaml index 1a7e955185d8..20d53fc5a5fa 100644 --- a/MdeModulePkg/MdeModulePkg.ci.yaml +++ b/MdeModulePkg/MdeModulePkg.ci.yaml @@ -104,7 +104,9 @@ "FVMAIN", "VARCHECKPCD", "Getxx", - "lzturbo" + "lzturbo", + "musthave", + "canthave" ], "AdditionalIncludePaths": [] # Additional paths to spell check rel= ative to package root (wildcards supported) } diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 82aecc40d9a9..51c7057bfd1b 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -31,6 +31,9 @@ [LibraryClasses] ## @libraryclass Defines a set of methods to reset whole system. ResetSystemLib|Include/Library/ResetSystemLib.h =20 + ## @libraryclass Business logic for storing and testing variable polic= ies + VariablePolicyLib|Include/Library/VariablePolicyLib.h + ## @libraryclass Defines a set of helper functions for resetting the s= ystem. ResetUtilityLib|Include/Library/ResetUtilityLib.h =20 diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index fbbc9933f5e8..3c8bf8009c55 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -3,6 +3,7 @@ # # (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) Microsoft Corporation. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -58,6 +59,7 @@ [LibraryClasses] DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableL= ib.inf UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManag= erLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ib.inf # # Generic Modules # @@ -129,6 +131,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ibRuntimeDxe.inf =20 [LibraryClasses.common.SMM_CORE] HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf @@ -306,6 +309,8 @@ [Components] MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf + MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf + MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf --=20 2.28.0.windows.1 -=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 (#67148): https://edk2.groups.io/g/devel/message/67148 Mute This Topic: https://groups.io/mt/78130771/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 Tue Apr 30 19:24:51 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+67149+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+67149+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1604904393; cv=none; d=zohomail.com; s=zohoarc; b=Wlmy3PiesrsR24L5+lhertuvheZPFw5gZoiAer5IKvyvlWs4EOtsdBng2Y0ll/Zh2cfYP1Dz17WuCOraok72RXL6yeGbKZ9flXJExymg+nPBoZA4hKCiQisXao4XUAFlr5ItfRDzVqYvyTnouahTTkIq7Kd+31CP62EWWdw6BEU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604904393; 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=xuCHN0FMn02xIqa0EB53au+gtuWylbSw0Qy1z3HkhEw=; b=aOJCTJ8vY03RmkzC5FVDm044zn1266NhCjAxZUg2DNEpkdKGZp59jwJ+WB1kwV3BhdtPkexSis+aHnbh2mxs+h79QHqKyJfc9G79CuQ4aEmz5pk9cAdqNcz8Bj/E8VFXj4KdX5GQNtfHQYd1CvYcL126tP6J28KXQ0Xrej3tkbU= 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+67149+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604904393536532.7933185588813; Sun, 8 Nov 2020 22:46:33 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id sRuhYY1788612xbulOLvRmPl; Sun, 08 Nov 2020 22:46:33 -0800 X-Received: from mail-pg1-f178.google.com (mail-pg1-f178.google.com [209.85.215.178]) by mx.groups.io with SMTP id smtpd.web09.7968.1604904387772078182 for ; Sun, 08 Nov 2020 22:46:27 -0800 X-Received: by mail-pg1-f178.google.com with SMTP id e21so6284846pgr.11 for ; Sun, 08 Nov 2020 22:46:27 -0800 (PST) X-Gm-Message-State: agNUQI5GgkwiUjgHg8n5IknSx1787277AA= X-Google-Smtp-Source: ABdhPJxusdq7Kms2a+fDdRHowkW1HsICFxa5dXZNo7CZpk//OzBVRf5No/Kf7zeZKJDS0zvYLTaZRw== X-Received: by 2002:a17:90b:4a07:: with SMTP id kk7mr11620320pjb.175.1604904386977; Sun, 08 Nov 2020 22:46:26 -0800 (PST) X-Received: from localhost.localdomain ([71.212.128.184]) by smtp.gmail.com with ESMTPSA id s145sm10215111pfs.187.2020.11.08.22.46.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Nov 2020 22:46:26 -0800 (PST) From: "Bret Barkelew" X-Google-Original-From: Bret Barkelew To: devel@edk2.groups.io Cc: Jian J Wang , Hao A Wu , Liming Gao , Bret Barkelew , Dandan Bi Subject: [edk2-devel] [PATCH v9 03/13] MdeModulePkg: Define the VariablePolicyHelperLib Date: Sun, 8 Nov 2020 22:45:12 -0800 Message-Id: <20201109064522.919-4-bret.barkelew@microsoft.com> In-Reply-To: <20201109064522.919-1-bret.barkelew@microsoft.com> References: <20201109064522.919-1-bret.barkelew@microsoft.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,bret@corthon.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604904393; bh=8JZpV3y6venmySBgRYhp+fzI3t4ADgc4Ubvd1Boisu0=; h=Cc:Date:From:Reply-To:Subject:To; b=JE6Cfqbg6u2aOEvkZHHQwbLtyNftb/yPZ2VcJ1rhtdgcCP755vQUWoTtxCMwqbbKvzx OT2kRnokppiE2XTDTT258rXN3kGtv3BBb5mNzdUJU7SHeve6Jz1nZQcna2Til8tWfabkU 8EizGUrA4QV4sMIsh85EAmybs+aUhGE3yCA= 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=3D2522 VariablePolicy is an updated interface to replace VarLock and VarCheckProtocol. Add the VariablePolicyHelperLib library, containing several functions to help with the repetitive process of creating a correctly structured and packed VariablePolicy entry. Cc: Jian J Wang Cc: Hao A Wu Cc: Liming Gao Cc: Bret Barkelew Signed-off-by: Bret Barkelew Reviewed-by: Dandan Bi Acked-by: Jian J Wang --- MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.c |= 396 ++++++++++++++++++++ MdeModulePkg/Include/Library/VariablePolicyHelperLib.h |= 164 ++++++++ MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf |= 35 ++ MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.uni |= 12 + MdeModulePkg/MdeModulePkg.dec |= 5 + MdeModulePkg/MdeModulePkg.dsc |= 2 + 6 files changed, 614 insertions(+) diff --git a/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHel= perLib.c b/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelpe= rLib.c new file mode 100644 index 000000000000..0c9299c8b0e1 --- /dev/null +++ b/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.c @@ -0,0 +1,396 @@ +/** @file -- VariablePolicyHelperLib.c +This library contains helper functions for marshalling and registering +new policies with the VariablePolicy infrastructure. + +This library is currently written against VariablePolicy revision 0x000100= 00. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include + +#include + +/** + This internal helper function populates the header structure, + all common fields, and takes care of fix-ups. + + NOTE: Only use this internally. Assumes correctly-sized buffers. + + @param[out] EntPtr Pointer to the buffer to be populated. + @param[in] Namespace Pointer to an EFI_GUID for the target variable n= amespace that this policy will protect. + @param[in] MinSize MinSize for the VariablePolicy. + @param[in] MaxSize MaxSize for the VariablePolicy. + @param[in] AttributesMustHave AttributesMustHave for the VariablePol= icy. + @param[in] AttributesCantHave AttributesCantHave for the VariablePol= icy. + @param[in] LockPolicyType LockPolicyType for the VariablePolicy. + +**/ +STATIC +VOID +PopulateCommonData ( + OUT VARIABLE_POLICY_ENTRY *EntPtr, + IN CONST EFI_GUID *Namespace, + IN UINT32 MinSize, + IN UINT32 MaxSize, + IN UINT32 AttributesMustHave, + IN UINT32 AttributesCantHave, + IN UINT8 LockPolicyType + ) +{ + EntPtr->Version =3D VARIABLE_POLICY_ENTRY_REVISION; + CopyGuid( &EntPtr->Namespace, Namespace ); + EntPtr->MinSize =3D MinSize; + EntPtr->MaxSize =3D MaxSize; + EntPtr->AttributesMustHave =3D AttributesMustHave; + EntPtr->AttributesCantHave =3D AttributesCantHave; + EntPtr->LockPolicyType =3D LockPolicyType; + + // NOTE: As a heler, fix up MaxSize for compatibility with the old model. + if (EntPtr->MaxSize =3D=3D 0) { + EntPtr->MaxSize =3D VARIABLE_POLICY_NO_MAX_SIZE; + } + + return; +} + + +/** + This helper function will allocate and populate a new VariablePolicy + structure for a policy that does not contain any sub-structures (such as + VARIABLE_LOCK_ON_VAR_STATE_POLICY). + + NOTE: Caller will need to free structure once finished. + + @param[in] Namespace Pointer to an EFI_GUID for the target variable n= amespace that this policy will protect. + @param[in] Name [Optional] If provided, a pointer to the CHAR16 = array for the target variable name. + Otherwise, will create a policy that targets an = entire namespace. + @param[in] MinSize MinSize for the VariablePolicy. + @param[in] MaxSize MaxSize for the VariablePolicy. + @param[in] AttributesMustHave AttributesMustHave for the VariablePol= icy. + @param[in] AttributesCantHave AttributesCantHave for the VariablePol= icy. + @param[in] LockPolicyType LockPolicyType for the VariablePolicy. + @param[out] NewEntry If successful, will be set to a pointer to the a= llocated buffer containing the + new policy. + + @retval EFI_SUCCESS Operation completed successfully and= structure is populated. + @retval EFI_INVALID_PARAMETER Namespace is NULL. + @retval EFI_INVALID_PARAMETER LockPolicyType is invalid for a basi= c structure. + @retval EFI_BUFFER_TOO_SMALL Finished structure would not fit in = UINT16 size. + @retval EFI_OUT_OF_RESOURCES Could not allocate sufficient space = for structure. + +**/ +EFI_STATUS +EFIAPI +CreateBasicVariablePolicy ( + IN CONST EFI_GUID *Namespace, + IN CONST CHAR16 *Name OPTIONAL, + IN UINT32 MinSize, + IN UINT32 MaxSize, + IN UINT32 AttributesMustHave, + IN UINT32 AttributesCantHave, + IN UINT8 LockPolicyType, + OUT VARIABLE_POLICY_ENTRY **NewEntry + ) +{ + UINTN TotalSize; + UINTN NameSize; + VARIABLE_POLICY_ENTRY *EntPtr; + CHAR16 *CopyName; + + // Check some initial invalid parameters for this function. + if (Namespace =3D=3D NULL || NewEntry =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + if (LockPolicyType !=3D VARIABLE_POLICY_TYPE_NO_LOCK && + LockPolicyType !=3D VARIABLE_POLICY_TYPE_LOCK_NOW && + LockPolicyType !=3D VARIABLE_POLICY_TYPE_LOCK_ON_CREATE) { + return EFI_INVALID_PARAMETER; + } + + // Now we've gotta determine the total size of the buffer required for + // the VariablePolicy structure. + TotalSize =3D sizeof( VARIABLE_POLICY_ENTRY ); + if (Name !=3D NULL) { + NameSize =3D StrnSizeS( Name, MAX_UINT16 ); + TotalSize +=3D NameSize; + } + // Make sure the size fits within a VARIABLE_POLICY_ENTRY.Size. + ASSERT( TotalSize <=3D MAX_UINT16 ); + if (TotalSize > MAX_UINT16) { + return EFI_BUFFER_TOO_SMALL; + } + + // Allocate a buffer to hold all the data. We're on the home stretch. + *NewEntry =3D AllocatePool( TotalSize ); + if (*NewEntry =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // If we're still here, we're basically done. + // Copy the data and GET... OUT.... + EntPtr =3D *NewEntry; + PopulateCommonData ( EntPtr, + Namespace, + MinSize, + MaxSize, + AttributesMustHave, + AttributesCantHave, + LockPolicyType ); + EntPtr->Size =3D (UINT16)TotalSize; // This is safe = because we've already checked. + EntPtr->OffsetToName =3D sizeof(VARIABLE_POLICY_ENTRY); + if (Name !=3D NULL) { + CopyName =3D (CHAR16*)((UINT8*)EntPtr + EntPtr->OffsetToName); + CopyMem( CopyName, Name, NameSize ); + } + + return EFI_SUCCESS; +} + + +/** + This helper function will allocate and populate a new VariablePolicy + structure for a policy with a lock type of VARIABLE_POLICY_TYPE_LOCK_ON_= VAR_STATE. + + NOTE: Caller will need to free structure once finished. + + @param[in] Namespace Pointer to an EFI_GUID for the target variable n= amespace that this policy will protect. + @param[in] Name [Optional] If provided, a pointer to the CHAR16 = array for the target variable name. + Otherwise, will create a policy that targets an = entire namespace. + @param[in] MinSize MinSize for the VariablePolicy. + @param[in] MaxSize MaxSize for the VariablePolicy. + @param[in] AttributesMustHave AttributesMustHave for the VariablePol= icy. + @param[in] AttributesCantHave AttributesCantHave for the VariablePol= icy. + @param[in] VarStateNamespace Pointer to the EFI_GUID for the VARIAB= LE_LOCK_ON_VAR_STATE_POLICY.Namespace. + @param[in] VarStateValue Value for the VARIABLE_LOCK_ON_VAR_STA= TE_POLICY.Value. + @param[in] VarStateName Pointer to the CHAR16 array for the VA= RIABLE_LOCK_ON_VAR_STATE_POLICY.Name. + @param[out] NewEntry If successful, will be set to a pointer to the a= llocated buffer containing the + new policy. + + @retval EFI_SUCCESS Operation completed successfully and= structure is populated. + @retval EFI_INVALID_PARAMETER Namespace, VarStateNamespace, VarSta= teName is NULL. + @retval EFI_BUFFER_TOO_SMALL Finished structure would not fit in = UINT16 size. + @retval EFI_OUT_OF_RESOURCES Could not allocate sufficient space = for structure. + +**/ +EFI_STATUS +EFIAPI +CreateVarStateVariablePolicy ( + IN CONST EFI_GUID *Namespace, + IN CONST CHAR16 *Name OPTIONAL, + IN UINT32 MinSize, + IN UINT32 MaxSize, + IN UINT32 AttributesMustHave, + IN UINT32 AttributesCantHave, + IN CONST EFI_GUID *VarStateNamespace, + IN UINT8 VarStateValue, + IN CONST CHAR16 *VarStateName, + OUT VARIABLE_POLICY_ENTRY **NewEntry + ) +{ + UINTN TotalSize; + UINTN NameSize; + UINTN VarStateNameSize; + VARIABLE_POLICY_ENTRY *EntPtr; + CHAR16 *CopyName; + VARIABLE_LOCK_ON_VAR_STATE_POLICY *CopyPolicy; + + // Check some initial invalid parameters for this function. + if (Namespace =3D=3D NULL || VarStateNamespace =3D=3D NULL || + VarStateName =3D=3D NULL || NewEntry =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // Now we've gotta determine the total size of the buffer required for + // the VariablePolicy structure. + VarStateNameSize =3D StrnSizeS( VarStateName, MAX_UINT16 ); + TotalSize =3D sizeof( VARIABLE_POLICY_ENTRY ) + + sizeof(VARIABLE_LOCK_ON_VAR_STATE_POLICY) + + VarStateNameSize; + if (Name !=3D NULL) { + NameSize =3D StrnSizeS( Name, MAX_UINT16 ); + TotalSize +=3D NameSize; + } + // Make sure the size fits within a VARIABLE_POLICY_ENTRY.Size. + ASSERT( TotalSize <=3D MAX_UINT16 ); + if (TotalSize > MAX_UINT16) { + return EFI_BUFFER_TOO_SMALL; + } + + // Allocate a buffer to hold all the data. We're on the home stretch. + *NewEntry =3D AllocatePool( TotalSize ); + if (*NewEntry =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // If we're still here, we're basically done. + // Copy the data and GET... OUT.... + EntPtr =3D *NewEntry; + PopulateCommonData ( EntPtr, + Namespace, + MinSize, + MaxSize, + AttributesMustHave, + AttributesCantHave, + VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE ); + EntPtr->Size =3D (UINT16)TotalSize; // This is safe = because we've already checked. + EntPtr->OffsetToName =3D sizeof(VARIABLE_POLICY_ENTRY) + + sizeof(VARIABLE_LOCK_ON_VAR_STATE_POLICY) + + (UINT16)VarStateNameSize; + + CopyPolicy =3D (VARIABLE_LOCK_ON_VAR_STATE_POLICY*)((UINT8*)EntPtr + siz= eof(VARIABLE_POLICY_ENTRY)); + CopyName =3D (CHAR16*)((UINT8*)CopyPolicy + sizeof(VARIABLE_LOCK_ON_VAR_= STATE_POLICY)); + CopyGuid( &CopyPolicy->Namespace, VarStateNamespace ); + CopyPolicy->Value =3D VarStateValue; + CopyMem( CopyName, VarStateName, VarStateNameSize ); + + if (Name !=3D NULL) { + CopyName =3D (CHAR16*)((UINT8*)EntPtr + EntPtr->OffsetToName); + CopyMem( CopyName, Name, NameSize ); + } + + return EFI_SUCCESS; +} + + +/** + This helper function does everything that CreateBasicVariablePolicy() do= es, but also + uses the passed in protocol to register the policy with the infrastructu= re. + Does not return a buffer, does not require the caller to free anything. + + @param[in] VariablePolicy Pointer to a valid instance of the VariableP= olicy protocol. + @param[in] Namespace Pointer to an EFI_GUID for the target variable n= amespace that this policy will protect. + @param[in] Name [Optional] If provided, a pointer to the CHAR16 = array for the target variable name. + Otherwise, will create a policy that targets an = entire namespace. + @param[in] MinSize MinSize for the VariablePolicy. + @param[in] MaxSize MaxSize for the VariablePolicy. + @param[in] AttributesMustHave AttributesMustHave for the VariablePol= icy. + @param[in] AttributesCantHave AttributesCantHave for the VariablePol= icy. + @param[in] LockPolicyType LockPolicyType for the VariablePolicy. + + @retval EFI_INVALID_PARAMETER VariablePolicy pointer is NULL. + @retval EFI_STATUS Status returned by CreateBasicVariable= Policy() or RegisterVariablePolicy(). + +**/ +EFI_STATUS +EFIAPI +RegisterBasicVariablePolicy ( + IN EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy, + IN CONST EFI_GUID *Namespace, + IN CONST CHAR16 *Name OPTIONAL, + IN UINT32 MinSize, + IN UINT32 MaxSize, + IN UINT32 AttributesMustHave, + IN UINT32 AttributesCantHave, + IN UINT8 LockPolicyType + ) +{ + VARIABLE_POLICY_ENTRY *NewEntry; + EFI_STATUS Status; + + // Check the simple things. + if (VariablePolicy =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // Create the new entry and make sure that everything worked. + NewEntry =3D NULL; + Status =3D CreateBasicVariablePolicy( Namespace, + Name, + MinSize, + MaxSize, + AttributesMustHave, + AttributesCantHave, + LockPolicyType, + &NewEntry ); + + // If that was successful, attempt to register the new policy. + if (!EFI_ERROR( Status )) { + Status =3D VariablePolicy->RegisterVariablePolicy( NewEntry ); + } + + // If we allocated the buffer, free the buffer. + if (NewEntry !=3D NULL) { + FreePool( NewEntry ); + } + + return Status; +} + + +/** + This helper function does everything that CreateBasicVariablePolicy() do= es, but also + uses the passed in protocol to register the policy with the infrastructu= re. + Does not return a buffer, does not require the caller to free anything. + + @param[in] VariablePolicy Pointer to a valid instance of the VariableP= olicy protocol. + @param[in] Namespace Pointer to an EFI_GUID for the target variable n= amespace that this policy will protect. + @param[in] Name [Optional] If provided, a pointer to the CHAR16 = array for the target variable name. + Otherwise, will create a policy that targets an = entire namespace. + @param[in] MinSize MinSize for the VariablePolicy. + @param[in] MaxSize MaxSize for the VariablePolicy. + @param[in] AttributesMustHave AttributesMustHave for the VariablePol= icy. + @param[in] AttributesCantHave AttributesCantHave for the VariablePol= icy. + @param[in] VarStateNamespace Pointer to the EFI_GUID for the VARIAB= LE_LOCK_ON_VAR_STATE_POLICY.Namespace. + @param[in] VarStateName Pointer to the CHAR16 array for the VA= RIABLE_LOCK_ON_VAR_STATE_POLICY.Name. + @param[in] VarStateValue Value for the VARIABLE_LOCK_ON_VAR_STA= TE_POLICY.Value. + + @retval EFI_INVALID_PARAMETER VariablePolicy pointer is NULL. + @retval EFI_STATUS Status returned by CreateBasicVariablePolicy()= or RegisterVariablePolicy(). + +**/ +EFI_STATUS +EFIAPI +RegisterVarStateVariablePolicy ( + IN EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy, + IN CONST EFI_GUID *Namespace, + IN CONST CHAR16 *Name OPTIONAL, + IN UINT32 MinSize, + IN UINT32 MaxSize, + IN UINT32 AttributesMustHave, + IN UINT32 AttributesCantHave, + IN CONST EFI_GUID *VarStateNamespace, + IN CONST CHAR16 *VarStateName, + IN UINT8 VarStateValue + ) +{ + VARIABLE_POLICY_ENTRY *NewEntry; + EFI_STATUS Status; + + // Check the simple things. + if (VariablePolicy =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // Create the new entry and make sure that everything worked. + NewEntry =3D NULL; + Status =3D CreateVarStateVariablePolicy( Namespace, + Name, + MinSize, + MaxSize, + AttributesMustHave, + AttributesCantHave, + VarStateNamespace, + VarStateValue, + VarStateName, + &NewEntry ); + + // If that was successful, attempt to register the new policy. + if (!EFI_ERROR( Status )) { + Status =3D VariablePolicy->RegisterVariablePolicy( NewEntry ); + } + + // If we allocated the buffer, free the buffer. + if (NewEntry !=3D NULL) { + FreePool( NewEntry ); + } + + return Status; +} diff --git a/MdeModulePkg/Include/Library/VariablePolicyHelperLib.h b/MdeMo= dulePkg/Include/Library/VariablePolicyHelperLib.h new file mode 100644 index 000000000000..3b75e9786094 --- /dev/null +++ b/MdeModulePkg/Include/Library/VariablePolicyHelperLib.h @@ -0,0 +1,164 @@ +/** @file -- VariablePolicyHelperLib.h +This library contains helper functions for marshalling and registering +new policies with the VariablePolicy infrastructure. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _EDKII_VARIABLE_POLICY_HELPER_LIB_H_ +#define _EDKII_VARIABLE_POLICY_HELPER_LIB_H_ + +#include + +/** + This helper function will allocate and populate a new VariablePolicy + structure for a policy that does not contain any sub-structures (such as + VARIABLE_LOCK_ON_VAR_STATE_POLICY). + + NOTE: Caller will need to free structure once finished. + + @param[in] Namespace Pointer to an EFI_GUID for the target variable n= amespace that this policy will protect. + @param[in] Name [Optional] If provided, a pointer to the CHAR16 = array for the target variable name. + Otherwise, will create a policy that targets an = entire namespace. + @param[in] MinSize MinSize for the VariablePolicy. + @param[in] MaxSize MaxSize for the VariablePolicy. + @param[in] AttributesMustHave AttributesMustHave for the VariablePol= icy. + @param[in] AttributesCantHave AttributesCantHave for the VariablePol= icy. + @param[in] LockPolicyType LockPolicyType for the VariablePolicy. + @param[out] NewEntry If successful, will be set to a pointer to the a= llocated buffer containing the + new policy. + + @retval EFI_SUCCESS Operation completed successfully and= structure is populated. + @retval EFI_INVALID_PARAMETER Namespace is NULL. + @retval EFI_INVALID_PARAMETER LockPolicyType is invalid for a basi= c structure. + @retval EFI_BUFFER_TOO_SMALL Finished structure would not fit in = UINT16 size. + @retval EFI_OUT_OF_RESOURCES Could not allocate sufficient space = for structure. + +**/ +EFI_STATUS +EFIAPI +CreateBasicVariablePolicy ( + IN CONST EFI_GUID *Namespace, + IN CONST CHAR16 *Name OPTIONAL, + IN UINT32 MinSize, + IN UINT32 MaxSize, + IN UINT32 AttributesMustHave, + IN UINT32 AttributesCantHave, + IN UINT8 LockPolicyType, + OUT VARIABLE_POLICY_ENTRY **NewEntry + ); + + +/** + This helper function will allocate and populate a new VariablePolicy + structure for a policy with a lock type of VARIABLE_POLICY_TYPE_LOCK_ON_= VAR_STATE. + + NOTE: Caller will need to free structure once finished. + + @param[in] Namespace Pointer to an EFI_GUID for the target variable n= amespace that this policy will protect. + @param[in] Name [Optional] If provided, a pointer to the CHAR16 = array for the target variable name. + Otherwise, will create a policy that targets an = entire namespace. + @param[in] MinSize MinSize for the VariablePolicy. + @param[in] MaxSize MaxSize for the VariablePolicy. + @param[in] AttributesMustHave AttributesMustHave for the VariablePol= icy. + @param[in] AttributesCantHave AttributesCantHave for the VariablePol= icy. + @param[in] VarStateNamespace Pointer to the EFI_GUID for the VARIAB= LE_LOCK_ON_VAR_STATE_POLICY.Namespace. + @param[in] VarStateValue Value for the VARIABLE_LOCK_ON_VAR_STA= TE_POLICY.Value. + @param[in] VarStateName Pointer to the CHAR16 array for the VA= RIABLE_LOCK_ON_VAR_STATE_POLICY.Name. + @param[out] NewEntry If successful, will be set to a pointer to the a= llocated buffer containing the + new policy. + + @retval EFI_SUCCESS Operation completed successfully and= structure is populated. + @retval EFI_INVALID_PARAMETER Namespace, VarStateNamespace, VarSta= teName is NULL. + @retval EFI_BUFFER_TOO_SMALL Finished structure would not fit in = UINT16 size. + @retval EFI_OUT_OF_RESOURCES Could not allocate sufficient space = for structure. + +**/ +EFI_STATUS +EFIAPI +CreateVarStateVariablePolicy ( + IN CONST EFI_GUID *Namespace, + IN CONST CHAR16 *Name OPTIONAL, + IN UINT32 MinSize, + IN UINT32 MaxSize, + IN UINT32 AttributesMustHave, + IN UINT32 AttributesCantHave, + IN CONST EFI_GUID *VarStateNamespace, + IN UINT8 VarStateValue, + IN CONST CHAR16 *VarStateName, + OUT VARIABLE_POLICY_ENTRY **NewEntry + ); + + +/** + This helper function does everything that CreateBasicVariablePolicy() do= es, but also + uses the passed in protocol to register the policy with the infrastructu= re. + Does not return a buffer, does not require the caller to free anything. + + @param[in] VariablePolicy Pointer to a valid instance of the VariableP= olicy protocol. + @param[in] Namespace Pointer to an EFI_GUID for the target variable n= amespace that this policy will protect. + @param[in] Name [Optional] If provided, a pointer to the CHAR16 = array for the target variable name. + Otherwise, will create a policy that targets an = entire namespace. + @param[in] MinSize MinSize for the VariablePolicy. + @param[in] MaxSize MaxSize for the VariablePolicy. + @param[in] AttributesMustHave AttributesMustHave for the VariablePol= icy. + @param[in] AttributesCantHave AttributesCantHave for the VariablePol= icy. + @param[in] LockPolicyType LockPolicyType for the VariablePolicy. + + @retval EFI_INVALID_PARAMETER VariablePolicy pointer is NULL. + @retval EFI_STATUS Status returned by CreateBasicVariable= Policy() or RegisterVariablePolicy(). + +**/ +EFI_STATUS +EFIAPI +RegisterBasicVariablePolicy ( + IN EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy, + IN CONST EFI_GUID *Namespace, + IN CONST CHAR16 *Name OPTIONAL, + IN UINT32 MinSize, + IN UINT32 MaxSize, + IN UINT32 AttributesMustHave, + IN UINT32 AttributesCantHave, + IN UINT8 LockPolicyType + ); + + +/** + This helper function does everything that CreateBasicVariablePolicy() do= es, but also + uses the passed in protocol to register the policy with the infrastructu= re. + Does not return a buffer, does not require the caller to free anything. + + @param[in] VariablePolicy Pointer to a valid instance of the VariableP= olicy protocol. + @param[in] Namespace Pointer to an EFI_GUID for the target variable n= amespace that this policy will protect. + @param[in] Name [Optional] If provided, a pointer to the CHAR16 = array for the target variable name. + Otherwise, will create a policy that targets an = entire namespace. + @param[in] MinSize MinSize for the VariablePolicy. + @param[in] MaxSize MaxSize for the VariablePolicy. + @param[in] AttributesMustHave AttributesMustHave for the VariablePol= icy. + @param[in] AttributesCantHave AttributesCantHave for the VariablePol= icy. + @param[in] VarStateNamespace Pointer to the EFI_GUID for the VARIAB= LE_LOCK_ON_VAR_STATE_POLICY.Namespace. + @param[in] VarStateName Pointer to the CHAR16 array for the VA= RIABLE_LOCK_ON_VAR_STATE_POLICY.Name. + @param[in] VarStateValue Value for the VARIABLE_LOCK_ON_VAR_STA= TE_POLICY.Value. + + @retval EFI_INVALID_PARAMETER VariablePolicy pointer is NULL. + @retval EFI_STATUS Status returned by CreateBasicVariablePolicy()= or RegisterVariablePolicy(). + +**/ +EFI_STATUS +EFIAPI +RegisterVarStateVariablePolicy ( + IN EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy, + IN CONST EFI_GUID *Namespace, + IN CONST CHAR16 *Name OPTIONAL, + IN UINT32 MinSize, + IN UINT32 MaxSize, + IN UINT32 AttributesMustHave, + IN UINT32 AttributesCantHave, + IN CONST EFI_GUID *VarStateNamespace, + IN CONST CHAR16 *VarStateName, + IN UINT8 VarStateValue + ); + +#endif // _EDKII_VARIABLE_POLICY_HELPER_LIB_H_ diff --git a/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHel= perLib.inf b/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHel= perLib.inf new file mode 100644 index 000000000000..506abf580e94 --- /dev/null +++ b/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.= inf @@ -0,0 +1,35 @@ +## @file VariablePolicyHelperLib.inf +# This library contains helper functions for marshalling and registering +# new policies with the VariablePolicy infrastructure. +# +# This library is currently written against VariablePolicy revision 0x0001= 0000. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + + +[Defines] + INF_VERSION =3D 0x00010017 + BASE_NAME =3D VariablePolicyHelperLib + # MODULE_UNI_FILE =3D VariablePolicyHelperLib.uni + FILE_GUID =3D B3C2206B-FDD1-4AED-8352-FC5EC34C5630 + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D BASE + LIBRARY_CLASS =3D VariablePolicyHelperLib + + +[Sources] + VariablePolicyHelperLib.c + + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +[LibraryClasses] + BaseLib + DebugLib + MemoryAllocationLib + BaseMemoryLib diff --git a/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHel= perLib.uni b/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHel= perLib.uni new file mode 100644 index 000000000000..39cbf11a4ce9 --- /dev/null +++ b/MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.= uni @@ -0,0 +1,12 @@ +// /** @file +// VariablePolicyHelperLib.uni +// +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Library containin= g helper functions for marshalling and registering new policies with the Va= riablePolicy infrastructure" + +#string STR_MODULE_DESCRIPTION #language en-US "Library containin= g helper functions for marshalling and registering new policies with the Va= riablePolicy infrastructure" diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 51c7057bfd1b..51f7f9d7246a 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -149,6 +149,11 @@ [LibraryClasses] # DisplayUpdateProgressLib|Include/Library/DisplayUpdateProgressLib.h =20 + ## @libraryclass This library contains helper functions for marshallin= g and + # registering new policies with the VariablePolicy infrastructure. + # + VariablePolicyHelperLib|Include/Library/VariablePolicyHelperLib.h + [Guids] ## MdeModule package token space guid # Include/Guid/MdeModulePkgTokenSpace.h diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 3c8bf8009c55..906550929002 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -99,6 +99,7 @@ [LibraryClasses] BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.i= nf SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLibGr= aphics/DisplayUpdateProgressLibGraphics.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/Var= iablePolicyHelperLib.inf =20 [LibraryClasses.EBC.PEIM] IoLib|MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf @@ -225,6 +226,7 @@ [Components] MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLib= Null.inf + MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf =20 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf --=20 2.28.0.windows.1 -=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 (#67149): https://edk2.groups.io/g/devel/message/67149 Mute This Topic: https://groups.io/mt/78130772/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 Tue Apr 30 19:24:51 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+67150+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+67150+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1604904396; cv=none; d=zohomail.com; s=zohoarc; b=U0KMruj5ROWaNGd/hh5IhNmxBA6xUDRD1gV9KpMaZipNjXf2Wkhfu82jBmjqjgu6UL25s3W4Q+atJWWoVybCpTVDXejJngu4d0GqKioOzisKJ5aChtZpJMBJTmsycAJQ/kf7D30SMmS+JMd4R2XF3WSTcrCokgyqx6R/jVqxuQY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604904396; 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=NKHCkYj8nYbFOYvutoZcLBXv90m0dCsynKX1K+RXC5E=; b=SM9aV7ssfFODSdxEQ1ZPjnhMsKA3fgYiqf1FYX4qn/gw6gLyoesdXPCJECT046MWYRTR6/2qqQuimZdmG4YWP2zmsyBSepAW4M/yufO2l8amB+GNi150WTpJ2vnYvZMUhPs2RgdqbLYCrYneH8NucN6Mzq63wMPghRTDwX/JNno= 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+67150+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604904396923736.9657000985061; Sun, 8 Nov 2020 22:46:36 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id rICXYY1788612xvUiDASX82O; Sun, 08 Nov 2020 22:46:36 -0800 X-Received: from mail-pl1-f196.google.com (mail-pl1-f196.google.com [209.85.214.196]) by mx.groups.io with SMTP id smtpd.web08.8044.1604904396070606935 for ; Sun, 08 Nov 2020 22:46:36 -0800 X-Received: by mail-pl1-f196.google.com with SMTP id j5so4254010plk.7 for ; Sun, 08 Nov 2020 22:46:36 -0800 (PST) X-Gm-Message-State: 2HXPxqZmNBNGLXIge2yXX26Yx1787277AA= X-Google-Smtp-Source: ABdhPJwCFrFLU108OkCXAiBvPWliJw7WAqBkblt1pZIshiENV1NKtzbYd3xoWDRHm9iLcgaTl17wiA== X-Received: by 2002:a17:902:402:b029:d5:ac47:c33f with SMTP id 2-20020a1709020402b02900d5ac47c33fmr11144919ple.60.1604904395263; Sun, 08 Nov 2020 22:46:35 -0800 (PST) X-Received: from localhost.localdomain ([71.212.128.184]) by smtp.gmail.com with ESMTPSA id s145sm10215111pfs.187.2020.11.08.22.46.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Nov 2020 22:46:34 -0800 (PST) From: "Bret Barkelew" X-Google-Original-From: Bret Barkelew To: devel@edk2.groups.io Cc: Jian J Wang , Hao A Wu , Liming Gao , Bret Barkelew , Dandan Bi Subject: [edk2-devel] [PATCH v9 04/13] MdeModulePkg: Define the VarCheckPolicyLib and SMM interface Date: Sun, 8 Nov 2020 22:45:13 -0800 Message-Id: <20201109064522.919-5-bret.barkelew@microsoft.com> In-Reply-To: <20201109064522.919-1-bret.barkelew@microsoft.com> References: <20201109064522.919-1-bret.barkelew@microsoft.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,bret@corthon.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604904396; bh=d4/npNZiMAfcZJ3nVmkf0/1sD6x6cbeNW9/zyyWPMTQ=; h=Cc:Date:From:Reply-To:Subject:To; b=wuHE4Z5qBUNiwZctdqIQG8K+q8TKXfgdUjwAQATovDEG4J731alCs/Xbk57hRL88OC7 hyB5VI9zsB22BJwD6+8VW117DpZFUSYDF0Rnjd0tL7sAnSZ6QafHComQXsXPOPVLwtnAb cp4KvSp0jTPady57JYMBqWpoXYTrk7xdkSg= 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=3D2522 VariablePolicy is an updated interface to replace VarLock and VarCheckProtocol. This is an instance of a VarCheckLib that is backed by the VariablePolicyLib business logic. It also publishes the SMM calling interface for messages from the DXE protocol. Cc: Jian J Wang Cc: Hao A Wu Cc: Liming Gao Cc: Bret Barkelew Signed-off-by: Bret Barkelew Reviewed-by: Dandan Bi Acked-by: Jian J Wang --- MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c | 346 +++++++= +++++++++++++ MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h | 54 +++ MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf | 42 +++ MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.uni | 12 + MdeModulePkg/MdeModulePkg.dec | 4 + MdeModulePkg/MdeModulePkg.dsc | 2 + 6 files changed, 460 insertions(+) diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c b/M= deModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c new file mode 100644 index 000000000000..257aa9591303 --- /dev/null +++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c @@ -0,0 +1,346 @@ +/** @file -- VarCheckPolicyLib.c +This is a NULL library instance that leverages the VarCheck interface +and the business logic behind the VariablePolicy code to make its decision= s. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +// As a VarCheck library, we're linked into the VariableServices +// and may not be able to call them indirectly. To get around this, +// use the internal GetVariable function to query the variable store. +//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =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 +VariableServiceGetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data + ); + + +UINT8 mSecurityEvalBuffer[VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE]; + +// Pagination Cache Variables +UINT8 *mPaginationCache =3D NULL; +UINTN mPaginationCacheSize =3D 0; +UINT32 mCurrentPaginationCommand =3D 0; + + +/** + MM Communication Handler to recieve commands from the DXE protocol for + Variable Policies. This communication channel is used to register new po= licies + and poll and toggle the enforcement of variable policies. + + @param[in] DispatchHandle All parameters standard to MM commun= ications convention. + @param[in] RegisterContext All parameters standard to MM commun= ications convention. + @param[in,out] CommBuffer All parameters standard to MM commun= ications convention. + @param[in,out] CommBufferSize All parameters standard to MM commun= ications convention. + + @retval EFI_SUCCESS + @retval EFI_INVALID_PARAMETER CommBuffer or CommBufferSize is null= pointer. + @retval EFI_INVALID_PARAMETER CommBuffer size is wrong. + @retval EFI_INVALID_PARAMETER Revision or signature don't match. + +**/ +STATIC +EFI_STATUS +EFIAPI +VarCheckPolicyLibMmiHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *RegisterContext, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommBufferSize + ) +{ + UINTN InternalCommBufferSize; + VOID *InternalCommBuffer; + EFI_STATUS Status; + EFI_STATUS SubCommandStatus; + VAR_CHECK_POLICY_COMM_HEADER *PolicyCommmHeader; + VAR_CHECK_POLICY_COMM_HEADER *InternalPolicyCommmHeader; + VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS *IsEnabledParams; + VAR_CHECK_POLICY_COMM_DUMP_PARAMS *DumpParamsIn; + VAR_CHECK_POLICY_COMM_DUMP_PARAMS *DumpParamsOut; + UINT8 *DumpInputBuffer; + UINT8 *DumpOutputBuffer; + UINTN DumpTotalPages; + VARIABLE_POLICY_ENTRY *PolicyEntry; + UINTN ExpectedSize; + UINT32 TempSize; + + Status =3D EFI_SUCCESS; + + // + // Validate some input parameters. + // + // If either of the pointers are NULL, we can't proceed. + if (CommBuffer =3D=3D NULL || CommBufferSize =3D=3D NULL) { + DEBUG(( DEBUG_INFO, "%a - Invalid comm buffer pointers!\n", __FUNCTION= __ )); + return EFI_INVALID_PARAMETER; + } + // Make sure that the buffer does not overlap SMM. + // This should be covered by the SmiManage infrastructure, but just to b= e safe... + InternalCommBufferSize =3D *CommBufferSize; + if (InternalCommBufferSize > VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE || !Sm= mIsBufferOutsideSmmValid((UINTN)CommBuffer, (UINT64)InternalCommBufferSize)= ) { + DEBUG ((DEBUG_ERROR, "%a - Invalid CommBuffer supplied! 0x%016lX[0x%01= 6lX]\n", __FUNCTION__, CommBuffer, InternalCommBufferSize)); + return EFI_INVALID_PARAMETER; + } + // If the size does not meet a minimum threshold, we cannot proceed. + ExpectedSize =3D sizeof(VAR_CHECK_POLICY_COMM_HEADER); + if (InternalCommBufferSize < ExpectedSize) { + DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNCTION= __, InternalCommBufferSize, ExpectedSize )); + return EFI_INVALID_PARAMETER; + } + + // + // Before proceeding any further, copy the buffer internally so that we = can compare + // without worrying about TOCTOU. + // + InternalCommBuffer =3D &mSecurityEvalBuffer[0]; + CopyMem(InternalCommBuffer, CommBuffer, InternalCommBufferSize); + PolicyCommmHeader =3D CommBuffer; + InternalPolicyCommmHeader =3D InternalCommBuffer; + // Check the revision and the signature of the comm header. + if (InternalPolicyCommmHeader->Signature !=3D VAR_CHECK_POLICY_COMM_SIG = || + InternalPolicyCommmHeader->Revision !=3D VAR_CHECK_POLICY_COMM_REVIS= ION) { + DEBUG(( DEBUG_INFO, "%a - Signature or revision are incorrect!\n", __F= UNCTION__ )); + // We have verified the buffer is not null and have enough size to hol= d Result field. + PolicyCommmHeader->Result =3D EFI_INVALID_PARAMETER; + return EFI_SUCCESS; + } + + // If we're in the middle of a paginated dump and any other command is s= ent, + // pagination cache must be cleared. + if (mPaginationCache !=3D NULL && InternalPolicyCommmHeader->Command != =3D mCurrentPaginationCommand) { + FreePool (mPaginationCache); + mPaginationCache =3D NULL; + mPaginationCacheSize =3D 0; + mCurrentPaginationCommand =3D 0; + } + + // + // Now we can process the command as it was sent. + // + PolicyCommmHeader->Result =3D EFI_ABORTED; // Set a default return fo= r incomplete commands. + switch(InternalPolicyCommmHeader->Command) { + case VAR_CHECK_POLICY_COMMAND_DISABLE: + PolicyCommmHeader->Result =3D DisableVariablePolicy(); + break; + + case VAR_CHECK_POLICY_COMMAND_IS_ENABLED: + // Make sure that we're dealing with a reasonable size. + // This add should be safe because these are fixed sizes so far. + ExpectedSize +=3D sizeof(VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS); + if (InternalCommBufferSize < ExpectedSize) { + DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNC= TION__, InternalCommBufferSize, ExpectedSize )); + PolicyCommmHeader->Result =3D EFI_INVALID_PARAMETER; + break; + } + + // Now that we know we've got a valid size, we can fill in the rest = of the data. + IsEnabledParams =3D (VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS*)((UINT= 8*)CommBuffer + sizeof(VAR_CHECK_POLICY_COMM_HEADER)); + IsEnabledParams->State =3D IsVariablePolicyEnabled(); + PolicyCommmHeader->Result =3D EFI_SUCCESS; + break; + + case VAR_CHECK_POLICY_COMMAND_REGISTER: + // Make sure that we're dealing with a reasonable size. + // This add should be safe because these are fixed sizes so far. + ExpectedSize +=3D sizeof(VARIABLE_POLICY_ENTRY); + if (InternalCommBufferSize < ExpectedSize) { + DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNC= TION__, InternalCommBufferSize, ExpectedSize )); + PolicyCommmHeader->Result =3D EFI_INVALID_PARAMETER; + break; + } + + // At the very least, we can assume that we're working with a valid = policy entry. + // Time to compare its internal size. + PolicyEntry =3D (VARIABLE_POLICY_ENTRY*)((UINT8*)InternalCommBuffer = + sizeof(VAR_CHECK_POLICY_COMM_HEADER)); + if (PolicyEntry->Version !=3D VARIABLE_POLICY_ENTRY_REVISION || + PolicyEntry->Size < sizeof(VARIABLE_POLICY_ENTRY) || + EFI_ERROR(SafeUintnAdd(sizeof(VAR_CHECK_POLICY_COMM_HEADER), Pol= icyEntry->Size, &ExpectedSize)) || + InternalCommBufferSize < ExpectedSize) { + DEBUG(( DEBUG_INFO, "%a - Bad policy entry contents!\n", __FUNCTIO= N__ )); + PolicyCommmHeader->Result =3D EFI_INVALID_PARAMETER; + break; + } + + PolicyCommmHeader->Result =3D RegisterVariablePolicy( PolicyEntry ); + break; + + case VAR_CHECK_POLICY_COMMAND_DUMP: + // Make sure that we're dealing with a reasonable size. + // This add should be safe because these are fixed sizes so far. + ExpectedSize +=3D sizeof(VAR_CHECK_POLICY_COMM_DUMP_PARAMS) + VAR_CH= ECK_POLICY_MM_DUMP_BUFFER_SIZE; + if (InternalCommBufferSize < ExpectedSize) { + DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNC= TION__, InternalCommBufferSize, ExpectedSize )); + PolicyCommmHeader->Result =3D EFI_INVALID_PARAMETER; + break; + } + + // Now that we know we've got a valid size, we can fill in the rest = of the data. + DumpParamsIn =3D (VAR_CHECK_POLICY_COMM_DUMP_PARAMS*)(InternalPolicy= CommmHeader + 1); + DumpParamsOut =3D (VAR_CHECK_POLICY_COMM_DUMP_PARAMS*)(PolicyCommmHe= ader + 1); + + // If we're requesting the first page, initialize the cache and get = the sizes. + if (DumpParamsIn->PageRequested =3D=3D 0) { + if (mPaginationCache !=3D NULL) { + FreePool (mPaginationCache); + mPaginationCache =3D NULL; + } + + // Determine what the required size is going to be. + DumpParamsOut->TotalSize =3D 0; + DumpParamsOut->PageSize =3D 0; + DumpParamsOut->HasMore =3D FALSE; + SubCommandStatus =3D DumpVariablePolicy (NULL, &TempSize); + if (SubCommandStatus =3D=3D EFI_BUFFER_TOO_SMALL && TempSize > 0) { + mCurrentPaginationCommand =3D VAR_CHECK_POLICY_COMMAND_DUMP; + mPaginationCacheSize =3D TempSize; + DumpParamsOut->TotalSize =3D TempSize; + mPaginationCache =3D AllocatePool (mPaginationCacheSize); + if (mPaginationCache =3D=3D NULL) { + SubCommandStatus =3D EFI_OUT_OF_RESOURCES; + } + } + + // If we've allocated our pagination cache, we're good to cache. + if (mPaginationCache !=3D NULL) { + SubCommandStatus =3D DumpVariablePolicy (mPaginationCache, &Temp= Size); + } + + // Populate the remaining fields and we can boogie. + if (!EFI_ERROR (SubCommandStatus) && mPaginationCache !=3D NULL) { + DumpParamsOut->HasMore =3D TRUE; + } + } else if (mPaginationCache !=3D NULL) { + DumpParamsOut->TotalSize =3D (UINT32)mPaginationCacheSize; + DumpOutputBuffer =3D (UINT8*)(DumpParamsOut + 1); + + // Make sure that we don't over-index the cache. + DumpTotalPages =3D mPaginationCacheSize / VAR_CHECK_POLICY_MM_DUMP= _BUFFER_SIZE; + if (mPaginationCacheSize % VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE != =3D 0) { + DumpTotalPages++; + } + if (DumpParamsIn->PageRequested > DumpTotalPages) { + SubCommandStatus =3D EFI_INVALID_PARAMETER; + } else { + // Figure out how far into the page cache we need to go for our = next page. + // We know the blind subtraction won't be bad because we already= checked for page 0. + DumpInputBuffer =3D &mPaginationCache[VAR_CHECK_POLICY_MM_DUMP_B= UFFER_SIZE * (DumpParamsIn->PageRequested - 1)]; + TempSize =3D VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE; + // If we're getting the last page, adjust the PageSize. + if (DumpParamsIn->PageRequested =3D=3D DumpTotalPages) { + TempSize =3D mPaginationCacheSize % VAR_CHECK_POLICY_MM_DUMP_B= UFFER_SIZE; + } + CopyMem (DumpOutputBuffer, DumpInputBuffer, TempSize); + DumpParamsOut->PageSize =3D TempSize; + // If we just got the last page, settle up the cache. + if (DumpParamsIn->PageRequested =3D=3D DumpTotalPages) { + DumpParamsOut->HasMore =3D FALSE; + FreePool (mPaginationCache); + mPaginationCache =3D NULL; + mPaginationCacheSize =3D 0; + mCurrentPaginationCommand =3D 0; + // Otherwise, we could do more here. + } else { + DumpParamsOut->HasMore =3D TRUE; + } + + // If we made it this far, we're basically good. + SubCommandStatus =3D EFI_SUCCESS; + } + // If we've requested any other page than 0 and the cache is empty, = we must have timed out. + } else { + DumpParamsOut->TotalSize =3D 0; + DumpParamsOut->PageSize =3D 0; + DumpParamsOut->HasMore =3D FALSE; + SubCommandStatus =3D EFI_TIMEOUT; + } + + // There's currently no use for this, but it shouldn't be hard to im= plement. + PolicyCommmHeader->Result =3D SubCommandStatus; + break; + + case VAR_CHECK_POLICY_COMMAND_LOCK: + PolicyCommmHeader->Result =3D LockVariablePolicy(); + break; + + default: + // Mark unknown requested command as EFI_UNSUPPORTED. + DEBUG(( DEBUG_INFO, "%a - Invalid command requested! %d\n", __FUNCTI= ON__, PolicyCommmHeader->Command )); + PolicyCommmHeader->Result =3D EFI_UNSUPPORTED; + break; + } + + DEBUG(( DEBUG_VERBOSE, "%a - Command %d returning %r.\n", __FUNCTION__, + PolicyCommmHeader->Command, PolicyCommmHeader->Result )); + + return Status; +} + + +/** + Constructor function of VarCheckPolicyLib to register VarCheck handler a= nd + SW MMI handlers. + + @param[in] ImageHandle The firmware allocated handle for the EFI imag= e. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor executed correctly. + +**/ +EFI_STATUS +EFIAPI +VarCheckPolicyLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE DiscardedHandle; + + // Initialize the business logic with the internal GetVariable handler. + Status =3D InitVariablePolicyLib( VariableServiceGetVariable ); + + // Only proceed with init if the business logic could be initialized. + if (!EFI_ERROR( Status )) { + // Register the VarCheck handler for SetVariable filtering. + // Forward the check to the business logic of the library. + VarCheckLibRegisterSetVariableCheckHandler( ValidateSetVariable ); + + // Register the MMI handlers for receiving policy commands. + DiscardedHandle =3D NULL; + Status =3D gMmst->MmiHandlerRegister( VarCheckPolicyLibMmiHandler, + &gVarCheckPolicyLibMmiHandlerGuid, + &DiscardedHandle ); + } + // Otherwise, there's not much we can do. + else { + DEBUG(( DEBUG_ERROR, "%a - Cannot Initialize VariablePolicyLib! %r\n",= __FUNCTION__, Status )); + ASSERT_EFI_ERROR( Status ); + } + + return Status; +} diff --git a/MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h b/MdeModulePkg/I= nclude/Guid/VarCheckPolicyMmi.h new file mode 100644 index 000000000000..77bcc62f3ccf --- /dev/null +++ b/MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h @@ -0,0 +1,54 @@ +/** @file -- VarCheckPolicyMmiCommon.h +This header contains communication definitions that are shared between DXE +and the MM component of VarCheckPolicy. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _VAR_CHECK_POLICY_MMI_COMMON_H_ +#define _VAR_CHECK_POLICY_MMI_COMMON_H_ + +#define VAR_CHECK_POLICY_COMM_SIG SIGNATURE_32('V', 'C', 'P', 'C') +#define VAR_CHECK_POLICY_COMM_REVISION 1 + +#pragma pack(push, 1) + +typedef struct _VAR_CHECK_POLICY_COMM_HEADER { + UINT32 Signature; + UINT32 Revision; + UINT32 Command; + EFI_STATUS Result; +} VAR_CHECK_POLICY_COMM_HEADER; + +typedef struct _VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS { + BOOLEAN State; +} VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS; + +typedef struct _VAR_CHECK_POLICY_COMM_DUMP_PARAMS { + UINT32 PageRequested; + UINT32 TotalSize; + UINT32 PageSize; + BOOLEAN HasMore; +} VAR_CHECK_POLICY_COMM_DUMP_PARAMS; + +#pragma pack(pop) + +// Make sure that we will hold at least the headers. +#define VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE MAX((OFFSET_OF(EFI_MM_COMM= UNICATE_HEADER, Data) + sizeof (VAR_CHECK_POLICY_COMM_HEADER) + EFI_PAGES_T= O_SIZE(1)), EFI_PAGES_TO_SIZE(4)) +#define VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE (VAR_CHECK_POLICY_MM_COMM_= BUFFER_SIZE - \ + (OFFSET_OF(EFI_MM_COMM= UNICATE_HEADER, Data) + \ + sizeof(VAR_CHECK_POL= ICY_COMM_HEADER) + \ + sizeof(VAR_CHECK_POL= ICY_COMM_DUMP_PARAMS))) +STATIC_ASSERT ( + VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE < VAR_CHECK_POLICY_MM_COMM_BUFFER_S= IZE, + "an integer underflow may have occurred calculating VAR_CHECK_POLICY_MM_= DUMP_BUFFER_SIZE" + ); + +#define VAR_CHECK_POLICY_COMMAND_DISABLE 0x0001 +#define VAR_CHECK_POLICY_COMMAND_IS_ENABLED 0x0002 +#define VAR_CHECK_POLICY_COMMAND_REGISTER 0x0003 +#define VAR_CHECK_POLICY_COMMAND_DUMP 0x0004 +#define VAR_CHECK_POLICY_COMMAND_LOCK 0x0005 + +#endif // _VAR_CHECK_POLICY_MMI_COMMON_H_ diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf b= /MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf new file mode 100644 index 000000000000..077bcc8990ca --- /dev/null +++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf @@ -0,0 +1,42 @@ +## @file VarCheckPolicyLib.inf +# This is an instance of a VarCheck lib that leverages the business logic = behind +# the VariablePolicy code to make its decisions. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D VarCheckPolicyLib + FILE_GUID =3D 9C28A48F-C884-4B1F-8B95-DEF125448023 + MODULE_TYPE =3D DXE_RUNTIME_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D NULL|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER + CONSTRUCTOR =3D VarCheckPolicyLibConstructor + + +[Sources] + VarCheckPolicyLib.c + + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +[LibraryClasses] + BaseLib + DebugLib + BaseMemoryLib + DxeServicesLib + MemoryAllocationLib + VarCheckLib + VariablePolicyLib + VariablePolicyHelperLib + SafeIntLib + MmServicesTableLib + + +[Guids] + gVarCheckPolicyLibMmiHandlerGuid ## CONSUME ## Used to register f= or MM Communication events. diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.uni b= /MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.uni new file mode 100644 index 000000000000..eedeeed15d31 --- /dev/null +++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.uni @@ -0,0 +1,12 @@ +// /** @file +// VarCheckPolicyLib.uni +// +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "NULL library impl= ementation that conforms to the VarCheck interface to allow VariablePolicy = engine to enforce policies" + +#string STR_MODULE_DESCRIPTION #language en-US "NULL library impl= ementation that conforms to the VarCheck interface to allow VariablePolicy = engine to enforce policies" diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 51f7f9d7246a..00075528198d 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -385,6 +385,10 @@ [Guids] ## Include/Guid/EndofS3Resume.h gEdkiiEndOfS3ResumeGuid =3D { 0x96f5296d, 0x05f7, 0x4f3c, {0x84, 0x67, 0= xe4, 0x56, 0x89, 0x0e, 0x0c, 0xb5 } } =20 + ## Used (similar to Variable Services) to communicate policies to the en= forcement engine. + # {DA1B0D11-D1A7-46C4-9DC9-F3714875C6EB} + gVarCheckPolicyLibMmiHandlerGuid =3D { 0xda1b0d11, 0xd1a7, 0x46c4, { 0x9= d, 0xc9, 0xf3, 0x71, 0x48, 0x75, 0xc6, 0xeb }} + ## Include/Guid/S3SmmInitDone.h gEdkiiS3SmmInitDoneGuid =3D { 0x8f9d4825, 0x797d, 0x48fc, { 0x84, 0x71, = 0x84, 0x50, 0x25, 0x79, 0x2e, 0xf6 } } =20 diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 906550929002..90165ca443bf 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -313,6 +313,7 @@ [Components] MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf + MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf @@ -458,6 +459,7 @@ [Components.IA32, Components.X64] MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf { + NULL|MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf NULL|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf NULL|MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf --=20 2.28.0.windows.1 -=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 (#67150): https://edk2.groups.io/g/devel/message/67150 Mute This Topic: https://groups.io/mt/78130774/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 Tue Apr 30 19:24:51 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+67151+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+67151+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1604904397; cv=none; d=zohomail.com; s=zohoarc; b=FFb2NPvBmhoxkKJLH5DepQ2tFr0sROSn8AO/U3nV5IDmNftq/muTlG/LiTAZqxRAGW6t+cYFnh61qHpQ/wxh1ZVA3eaaqjyZJ7iiphoq/0vIM9xRkgHWykjae1Hdqqlouaa9+3mOxbDRj5LA0YpnuVxtdoicSN7pISY13xVkwCc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604904397; 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=U6FT+5/6skaQbnofSzZ1dv0/Hb/hLB1Q1b9xHDAfWgA=; b=YzhG2xjOuCm3fGPQ3gsBlAz5L+7UlrWkDpgDfJsH9Na7/sU/LjRSAU7MK4bmCao35wUWttFcWRwuWUkeWVAVv6PU9OrsGdMyonFNl8aKg35Kbiyeu7ecCtBf+gNrxVnAUM7Ap47RXK5D+TZpkv00vGf8+2lZ1bxE9Jocj073ino= 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+67151+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604904397761576.1278788171488; Sun, 8 Nov 2020 22:46:37 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 7lWlYY1788612xqTHkk3SjRE; Sun, 08 Nov 2020 22:46:37 -0800 X-Received: from mail-pf1-f179.google.com (mail-pf1-f179.google.com [209.85.210.179]) by mx.groups.io with SMTP id smtpd.web10.7935.1604904396985487292 for ; Sun, 08 Nov 2020 22:46:37 -0800 X-Received: by mail-pf1-f179.google.com with SMTP id a18so7010457pfl.3 for ; Sun, 08 Nov 2020 22:46:36 -0800 (PST) X-Gm-Message-State: 7kikxm6DSvEHnxopwWbDPouZx1787277AA= X-Google-Smtp-Source: ABdhPJziR5ENACDICbqhK+QKhwAiksr6mi57hwOdg9qdXuPaKrcMPQE3FvAvJAc8qKhiXsK56DsLEw== X-Received: by 2002:a62:2a81:0:b029:18c:310f:74fe with SMTP id q123-20020a622a810000b029018c310f74femr386814pfq.50.1604904396254; Sun, 08 Nov 2020 22:46:36 -0800 (PST) X-Received: from localhost.localdomain ([71.212.128.184]) by smtp.gmail.com with ESMTPSA id s145sm10215111pfs.187.2020.11.08.22.46.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Nov 2020 22:46:35 -0800 (PST) From: "Bret Barkelew" X-Google-Original-From: Bret Barkelew To: devel@edk2.groups.io Cc: Jordan Justen , Laszlo Ersek , Ard Biesheuvel , Bret Barkelew Subject: [edk2-devel] [PATCH v9 05/13] OvmfPkg: Add VariablePolicy engine to OvmfPkg platform Date: Sun, 8 Nov 2020 22:45:14 -0800 Message-Id: <20201109064522.919-6-bret.barkelew@microsoft.com> In-Reply-To: <20201109064522.919-1-bret.barkelew@microsoft.com> References: <20201109064522.919-1-bret.barkelew@microsoft.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,bret@corthon.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604904397; bh=ywiiphlkODpXYroYT4FoKeuQ7gmMbrs8SVE5Hmp6kI4=; h=Cc:Date:From:Reply-To:Subject:To; b=dA0P1Qz5OwKxETdgcWWztXE1cHqM/NDdhR5oqousFDUctpNFB3fYbkHIQVngLiUuuXA eR3UCmuIf5Hucd/qxLc8SGCUxicBCmOMQEqio1uZww4/O8Dnp5hwU/WywV0gLY1j6P5Y1 xrO0SSeEQ+SqqNCW1PFa2GhSzequ12e/QK8= 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=3D2522 Cc: Jordan Justen Cc: Laszlo Ersek Cc: Ard Biesheuvel Cc: Bret Barkelew Signed-off-by: Bret Barkelew Reviewed-by: Laszlo Ersek --- OvmfPkg/OvmfPkgIa32.dsc | 5 +++++ OvmfPkg/OvmfPkgIa32X64.dsc | 5 +++++ OvmfPkg/OvmfPkgX64.dsc | 5 +++++ OvmfPkg/OvmfXen.dsc | 4 ++++ 4 files changed, 19 insertions(+) diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 58d9f292f9ac..8a45a95d51d5 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -3,6 +3,7 @@ # # Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
+# Copyright (c) Microsoft Corporation. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -198,6 +199,8 @@ [LibraryClasses] AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLib= Null.inf !endif VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/Var= iablePolicyHelperLib.inf =20 =20 # @@ -337,6 +340,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ibRuntimeDxe.inf =20 [LibraryClasses.common.UEFI_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -968,6 +972,7 @@ [Components] MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf { NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + NULL|MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf } MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf =20 diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 3551f9710a6c..2ce5c2681d26 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -3,6 +3,7 @@ # # Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
+# Copyright (c) Microsoft Corporation. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -202,6 +203,8 @@ [LibraryClasses] AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLib= Null.inf !endif VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/Var= iablePolicyHelperLib.inf =20 =20 # @@ -341,6 +344,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ibRuntimeDxe.inf =20 [LibraryClasses.common.UEFI_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -983,6 +987,7 @@ [Components.X64] MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf { NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + NULL|MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf } MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf =20 diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 7a8bdb8a8697..66fb264149fc 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -3,6 +3,7 @@ # # Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
+# Copyright (c) Microsoft Corporation. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -202,6 +203,8 @@ [LibraryClasses] AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLib= Null.inf !endif VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/Var= iablePolicyHelperLib.inf =20 =20 # @@ -341,6 +344,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ibRuntimeDxe.inf =20 [LibraryClasses.common.UEFI_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -979,6 +983,7 @@ [Components] MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf { NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + NULL|MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf } MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf =20 diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc index 34c9de19dfba..26c29e083948 100644 --- a/OvmfPkg/OvmfXen.dsc +++ b/OvmfPkg/OvmfXen.dsc @@ -4,6 +4,7 @@ # Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.
# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
# Copyright (c) 2019, Citrix Systems, Inc. +# Copyright (c) Microsoft Corporation. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -183,6 +184,8 @@ [LibraryClasses] =20 AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLib= Null.inf VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/Var= iablePolicyHelperLib.inf =20 =20 # @@ -291,6 +294,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/DxeQemuFwCfgS3LibFwCfg.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ibRuntimeDxe.inf =20 [LibraryClasses.common.UEFI_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf --=20 2.28.0.windows.1 -=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 (#67151): https://edk2.groups.io/g/devel/message/67151 Mute This Topic: https://groups.io/mt/78130775/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 Tue Apr 30 19:24:51 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+67152+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+67152+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1604904403; cv=none; d=zohomail.com; s=zohoarc; b=I9DjOFVIQqTcSNIx/L9UtmEyUfHvql2Apm6QJXPWmSoFBtM6BhteKk6RzEw25Unq8SjrqIDX+4FbV/RCRA6TwaEHNYw4Xpx7mmMKk4QsvW51Ka11dHtEU1SAwG0KL82sWjz4GTAgkN9UIjJMHzOoRKWTsMf8VKJFSYquUr+ozy4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604904403; 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=5APmkMEXq/oBQUz+szU4QIq2FnEQHtuvh7+0cYabi5c=; b=iwtH9v6T7cFUSPCgccG/bwJ1+CgPnXbI2a8mOLEX44S0g1S9GzvJrfbOsX5sqEyx30tRfrbNtJua3RxTyjxPumjR0TC+RBm2la9fbTsqsABnxMfctqaelsS5ta351Nev8goROAMBBVllgXhSWf7380JLduWB3K10WAb/kfRwvI4= 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+67152+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604904403525808.022730355083; Sun, 8 Nov 2020 22:46:43 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id ubzlYY1788612xkE1zh48Z3B; Sun, 08 Nov 2020 22:46:43 -0800 X-Received: from mail-pg1-f178.google.com (mail-pg1-f178.google.com [209.85.215.178]) by mx.groups.io with SMTP id smtpd.web09.7969.1604904397756949608 for ; Sun, 08 Nov 2020 22:46:37 -0800 X-Received: by mail-pg1-f178.google.com with SMTP id x13so6297873pgp.7 for ; Sun, 08 Nov 2020 22:46:37 -0800 (PST) X-Gm-Message-State: 3GbRrnpDRSjWCm2B9wFPvcvgx1787277AA= X-Google-Smtp-Source: ABdhPJyeF5+OI6s2aX2LCjkoGs7VLslfsB7wslaFjjCV+/SL8c0B8YEVTnmQi4mOuTqu6RRFgZV/9g== X-Received: by 2002:a17:90b:ec2:: with SMTP id gz2mr10804734pjb.211.1604904397174; Sun, 08 Nov 2020 22:46:37 -0800 (PST) X-Received: from localhost.localdomain ([71.212.128.184]) by smtp.gmail.com with ESMTPSA id s145sm10215111pfs.187.2020.11.08.22.46.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Nov 2020 22:46:36 -0800 (PST) From: "Bret Barkelew" X-Google-Original-From: Bret Barkelew To: devel@edk2.groups.io Cc: Jordan Justen , Andrew Fish , Ray Ni , Bret Barkelew Subject: [edk2-devel] [PATCH v9 06/13] EmulatorPkg: Add VariablePolicy engine to EmulatorPkg platform Date: Sun, 8 Nov 2020 22:45:15 -0800 Message-Id: <20201109064522.919-7-bret.barkelew@microsoft.com> In-Reply-To: <20201109064522.919-1-bret.barkelew@microsoft.com> References: <20201109064522.919-1-bret.barkelew@microsoft.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,bret@corthon.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604904403; bh=xxgIYi1iDUK3P5vZA5PJgq61tZH8/CzF3NYwLWc0zNM=; h=Cc:Date:From:Reply-To:Subject:To; b=JaJJb2amWV2qYxWq9AFagzH05RuNlwKTpLRsi7AnSER0lL+hPgvfLdI9gYTgY8AVso1 1cMb3vAA5bOiv4cfY0iyMlfbUJ/L9pFSnrxTM4BCwDnfN/ritkt9AIjp4UybqjfmleNw8 33+ShXeD9ONX/WR8H1VpWrTIeHz7k+J+z1M= 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=3D2522 Cc: Jordan Justen Cc: Andrew Fish Cc: Ray Ni Cc: Bret Barkelew Signed-off-by: Bret Barkelew Reviewed-by: Ray Ni --- EmulatorPkg/EmulatorPkg.dsc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc index a27cb1beb0f1..c48e36a72c60 100644 --- a/EmulatorPkg/EmulatorPkg.dsc +++ b/EmulatorPkg/EmulatorPkg.dsc @@ -6,6 +6,7 @@ # # Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.
# Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved.
+# Copyright (c) Microsoft Corporation. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -108,6 +109,8 @@ [LibraryClasses] CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/C= puExceptionHandlerLibNull.inf TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurem= entLibNull.inf VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ibRuntimeDxe.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/Var= iablePolicyHelperLib.inf SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf --=20 2.28.0.windows.1 -=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 (#67152): https://edk2.groups.io/g/devel/message/67152 Mute This Topic: https://groups.io/mt/78130776/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 Tue Apr 30 19:24:51 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+67153+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+67153+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1604904400; cv=none; d=zohomail.com; s=zohoarc; b=KoN4N+JIdm14yyOq1pCv1+Ga/sJNHeTbeHRCSvyDaGqbFNzwsrQrVJ/+VyGk5fqAWWFQQlm2fFQZNp9ZFwEotacCm6tA/Scr5XpKKx7c5kEFHykbOWekjHrcs2fIBLbD/mdZAtR9fGIjz5Az78rLFit8uJmXD3I/4ViOQpD0Gl4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604904400; 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=pM0M3EW5TN3Ku5EIhcBjsXDlx7dVnAn424OudwN28F8=; b=Y2bZKI5kbtT8zWLa+uxPUwnBBCBBNgYUBzF/9Q487JK5mTi/JLHKSX56GERZmTt+dAuwK+Zn2V7Xrlf8MrydZ4L/s7Vpnldoh9fl88d06kflJFtxRrE9QTo8mS2ayQCr0KFYAhw5AC9+Mwxmyr+pSs+G44vRCIuXEAGm61gBkT4= 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+67153+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604904400661856.7670991438171; Sun, 8 Nov 2020 22:46:40 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id U9nXYY1788612xfZ6KANXQnI; Sun, 08 Nov 2020 22:46:40 -0800 X-Received: from mail-pf1-f173.google.com (mail-pf1-f173.google.com [209.85.210.173]) by mx.groups.io with SMTP id smtpd.web08.8046.1604904399466359928 for ; Sun, 08 Nov 2020 22:46:39 -0800 X-Received: by mail-pf1-f173.google.com with SMTP id y7so7175863pfq.11 for ; Sun, 08 Nov 2020 22:46:39 -0800 (PST) X-Gm-Message-State: KQklKeWuzoaLeLGfHua7phjwx1787277AA= X-Google-Smtp-Source: ABdhPJwoxlJHSMZvgc8Ftc3TGMUvlNPmsF1seePr0OVHRf0BMKbSss08CGKGX3ohfiupS3tuZButPw== X-Received: by 2002:a17:90a:80c6:: with SMTP id k6mr11415243pjw.73.1604904398642; Sun, 08 Nov 2020 22:46:38 -0800 (PST) X-Received: from localhost.localdomain ([71.212.128.184]) by smtp.gmail.com with ESMTPSA id s145sm10215111pfs.187.2020.11.08.22.46.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Nov 2020 22:46:37 -0800 (PST) From: "Bret Barkelew" X-Google-Original-From: Bret Barkelew To: devel@edk2.groups.io Cc: Laszlo Ersek , Ard Biesheuvel , Leif Lindholm , Bret Barkelew Subject: [edk2-devel] [PATCH v9 07/13] ArmVirtPkg: Add VariablePolicy engine to ArmVirtPkg platform Date: Sun, 8 Nov 2020 22:45:16 -0800 Message-Id: <20201109064522.919-8-bret.barkelew@microsoft.com> In-Reply-To: <20201109064522.919-1-bret.barkelew@microsoft.com> References: <20201109064522.919-1-bret.barkelew@microsoft.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,bret@corthon.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604904400; bh=eNuM43YaaOvyExcda+QCgjEvaoTuOucuGsG2ra2sy2w=; h=Cc:Date:From:Reply-To:Subject:To; b=A2UlG8jhQS6RjRGe1acQDXKUTz2V8YLEY1H8NE9hr/mHg/e/P0rEM3linIhvqRWzigc Sgt6O6ij60N5BOaJ357il7E9kJpcSbZqOllOTSoeUzggH/iHBwa+38aZOWFyi10SZOKNN GYMBi/OaXmK39PT4kVNnhFuu76D3BOdsQR0= 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=3D2522 Cc: Laszlo Ersek Cc: Ard Biesheuvel Cc: Leif Lindholm Cc: Bret Barkelew Signed-off-by: Bret Barkelew Reviewed-by: Laszlo Ersek --- ArmVirtPkg/ArmVirt.dsc.inc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 4dafd1fa0f1d..9ec92930472d 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -2,6 +2,7 @@ # Copyright (c) 2011-2015, ARM Limited. All rights reserved. # Copyright (c) 2014, Linaro Limited. All rights reserved. # Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved. +# Copyright (c) Microsoft Corporation. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -174,6 +175,8 @@ [LibraryClasses.common] AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLib= Null.inf !endif VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/Var= iablePolicyHelperLib.inf UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManag= erLib.inf =20 ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseRepor= tStatusCodeLibNull.inf @@ -247,6 +250,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] !if $(TARGET) !=3D RELEASE DebugLib|MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibS= erialPort.inf !endif + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ibRuntimeDxe.inf =20 !if $(SECURE_BOOT_ENABLE) =3D=3D TRUE BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf --=20 2.28.0.windows.1 -=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 (#67153): https://edk2.groups.io/g/devel/message/67153 Mute This Topic: https://groups.io/mt/78130777/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 Tue Apr 30 19:24:51 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+67154+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+67154+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1604904406; cv=none; d=zohomail.com; s=zohoarc; b=EM8NNGtouvqxPs3plI3h8uS36Nv7HayheYBAN3BG1p9ULcMBfaqt/BIsNOy+1DMVh9BpEA/LTGcJz9AJ8qQmv/Ug7lGffbpZ0YXneZbFxjmLrPA0DAGZXLp2zgp+uAY7fWdowDLjpEZncaZX+2WaWQMkV77CNF1RhaKZcexxIuE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604904406; 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=hgXL/ZwPBeQw1clBt9hFoZkTSVWnGxFoOLzi1T8fSGA=; b=fHxJG5aLFKv8BDiCEZmyrXBL1L9yEis7TftRzrTMMWUAOHSYAnnDHQSWneAZZmYMU1N0IAC1Nwath0ouNlaCaQZgR40BTg0B9/s/Z6UQF4xNp0VMXnr7PAwcyKDDY171eiqSvjlBuihP9YPdgQDDfwcpOuqMKwmVOI0U7zxEYZg= 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+67154+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604904406683223.91019454847162; Sun, 8 Nov 2020 22:46:46 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 7DxWYY1788612xucw0IMPSQy; Sun, 08 Nov 2020 22:46:45 -0800 X-Received: from mail-pf1-f178.google.com (mail-pf1-f178.google.com [209.85.210.178]) by mx.groups.io with SMTP id smtpd.web08.8047.1604904400328777221 for ; Sun, 08 Nov 2020 22:46:40 -0800 X-Received: by mail-pf1-f178.google.com with SMTP id g7so7201866pfc.2 for ; Sun, 08 Nov 2020 22:46:40 -0800 (PST) X-Gm-Message-State: pfyIdHQJwWp39Dtwk0ejuXfPx1787277AA= X-Google-Smtp-Source: ABdhPJyrtNA8dSSEe6qshSWXEc6wPCiGLXSFMErswVExFqffi4Ua6E4JdgJU7u6f5PMIeuz1VGdeeQ== X-Received: by 2002:a17:90a:5c82:: with SMTP id r2mr11445043pji.69.1604904399689; Sun, 08 Nov 2020 22:46:39 -0800 (PST) X-Received: from localhost.localdomain ([71.212.128.184]) by smtp.gmail.com with ESMTPSA id s145sm10215111pfs.187.2020.11.08.22.46.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Nov 2020 22:46:39 -0800 (PST) From: "Bret Barkelew" X-Google-Original-From: Bret Barkelew To: devel@edk2.groups.io Cc: Maurice Ma , Guo Dong , Benjamin You , Bret Barkelew Subject: [edk2-devel] [PATCH v9 08/13] UefiPayloadPkg: Add VariablePolicy engine to UefiPayloadPkg platform Date: Sun, 8 Nov 2020 22:45:17 -0800 Message-Id: <20201109064522.919-9-bret.barkelew@microsoft.com> In-Reply-To: <20201109064522.919-1-bret.barkelew@microsoft.com> References: <20201109064522.919-1-bret.barkelew@microsoft.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,bret@corthon.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604904405; bh=4pCReg/JJMjvZnohqje39J/axMf6nrXAHJF0osDK+rE=; h=Cc:Date:From:Reply-To:Subject:To; b=ngt7wU2K3b7VvktcWoqd3FdciTG5QbY5BPw7GtQUOd2FEE/koSMl+LXpDEzUMCsjbqq XJI3TSbltBDEoCZZm1iIC29YFAT2b038jt+zlvCB+Jb4yWXRDnwSSfOfTUIxiayu6mkXW 10qDzXunTydnOjG283pAuhi3Ogsi/mFvnJ8= 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=3D2522 Cc: Maurice Ma Cc: Guo Dong Cc: Benjamin You Cc: Bret Barkelew Signed-off-by: Bret Barkelew Reviewed-by: Maurice Ma --- UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 4 ++++ UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPay= loadPkgIa32.dsc index 12d7ffe81416..2206ccdc94c4 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -4,6 +4,7 @@ # Provides drivers and definitions to create uefi payload for bootloaders. # # Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.
+# Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -208,6 +209,8 @@ [LibraryClasses] AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLib= Null.inf TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurem= entLibNull.inf VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/Var= iablePolicyHelperLib.inf =20 [LibraryClasses.IA32.SEC] DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf @@ -257,6 +260,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAll= ocationLib.inf ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/R= untimeDxeReportStatusCodeLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ibRuntimeDxe.inf =20 [LibraryClasses.common.UEFI_DRIVER,LibraryClasses.common.UEFI_APPLICATION] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/Uefi= PayloadPkgIa32X64.dsc index e18c4678e8e3..cc34fd520b9a 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc @@ -4,6 +4,7 @@ # Provides drivers and definitions to create uefi payload for bootloaders. # # Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.
+# Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -209,6 +210,8 @@ [LibraryClasses] AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLib= Null.inf TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurem= entLibNull.inf VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/Var= iablePolicyHelperLib.inf =20 [LibraryClasses.IA32.SEC] DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf @@ -258,6 +261,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAll= ocationLib.inf ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/R= untimeDxeReportStatusCodeLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyL= ibRuntimeDxe.inf =20 [LibraryClasses.common.UEFI_DRIVER,LibraryClasses.common.UEFI_APPLICATION] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf --=20 2.28.0.windows.1 -=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 (#67154): https://edk2.groups.io/g/devel/message/67154 Mute This Topic: https://groups.io/mt/78130778/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 Tue Apr 30 19:24:51 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+67155+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+67155+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1604904402; cv=none; d=zohomail.com; s=zohoarc; b=XAHee/pAT6uv3J5N5PaJgtQ5wHpsI8ggcTw8fc7pgDqqPdq1j+ODXG1JapGx6OpaS27OgpVfiBBtnrgFabnfjQggmaBvByOa1m5EGAvnGkJpEMpa0lntdQ6jD0nWastwthkVUHiLvzIFsYADR/AVN2i30zwlusSx9wmJwbUJvFc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604904402; 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=XFgRyUbY8/jl8rknNoiIAMZWo6i7SWmeq16A7kG50y8=; b=fmWFu7pmuGgg40q6pUXom1AtAomRyuCGKmPhTi2waKYPLC/+Szks4Onz4DoZ50PHfTfCvxkspurbnYo3HCPm5wxw4qhIWHO3KxqGlJnECiGtIYXjEyPRxeEwOdIX54YgAIrUTR3ALvKVSv4PW4bn2ps1m0WBLZTsfBpT4Xvn8CY= 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+67155+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604904402422349.61520835339104; Sun, 8 Nov 2020 22:46:42 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 3DAlYY1788612x7hnp4tUfky; Sun, 08 Nov 2020 22:46:42 -0800 X-Received: from mail-pf1-f181.google.com (mail-pf1-f181.google.com [209.85.210.181]) by mx.groups.io with SMTP id smtpd.web11.8062.1604904401558157566 for ; Sun, 08 Nov 2020 22:46:41 -0800 X-Received: by mail-pf1-f181.google.com with SMTP id z3so7174993pfb.10 for ; Sun, 08 Nov 2020 22:46:41 -0800 (PST) X-Gm-Message-State: 82HVVIDwtybMk9hjfbghkySUx1787277AA= X-Google-Smtp-Source: ABdhPJyPnatJzS1LFoutH0csPZj7q/ZsP+ZV/OKxLOW+91yQmm3rwJA7itpcocMM0U6kNhER+kFTOQ== X-Received: by 2002:a62:1a48:0:b029:18a:b64f:44eb with SMTP id a69-20020a621a480000b029018ab64f44ebmr12240745pfa.79.1604904400709; Sun, 08 Nov 2020 22:46:40 -0800 (PST) X-Received: from localhost.localdomain ([71.212.128.184]) by smtp.gmail.com with ESMTPSA id s145sm10215111pfs.187.2020.11.08.22.46.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Nov 2020 22:46:40 -0800 (PST) From: "Bret Barkelew" X-Google-Original-From: Bret Barkelew To: devel@edk2.groups.io Cc: Jian J Wang , Hao A Wu , Liming Gao , Bret Barkelew , Dandan Bi Subject: [edk2-devel] [PATCH v9 09/13] MdeModulePkg: Connect VariablePolicy business logic to VariableServices Date: Sun, 8 Nov 2020 22:45:18 -0800 Message-Id: <20201109064522.919-10-bret.barkelew@microsoft.com> In-Reply-To: <20201109064522.919-1-bret.barkelew@microsoft.com> References: <20201109064522.919-1-bret.barkelew@microsoft.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,bret@corthon.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604904402; bh=CwcVkWfGIw1QDgplstVqZ2h/pUJs1LvWL1vFp4ibRB8=; h=Cc:Date:From:Reply-To:Subject:To; b=Y0OpKicj8QsUm3JjqcOBxEnRharsty06SyPPPooZkxnLKe/pWN8y8OpcIzscGXj7gto jPR26QXhABbe1NJNuYU6NOsdGe3XVOPF3btWn6GHZ2ZN0Fdk0HJO/M5HkuGWvwz8hFR6k j09uvMst00BtFk4TQ9pQ0l5rhi3lV+hrgDs= 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=3D2522 VariablePolicy is an updated interface to replace VarLock and VarCheckProtocol. Add connective code to publish the VariablePolicy protocol and wire it to either the SMM communication interface or directly into the VariablePolicyLib business logic. Cc: Jian J Wang Cc: Hao A Wu Cc: Liming Gao Cc: Bret Barkelew Signed-off-by: Bret Barkelew Reviewed-by: Dandan Bi Acked-by: Jian J Wang --- MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c | 60= ++ MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c | 573= ++++++++++++++++++++ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c | 7= + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c | 14= + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf | 2= + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf | 3= + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf | 11= + 7 files changed, 670 insertions(+) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c b/Mde= ModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c index 7d2b6c8e1fad..0fca0bb2a9b5 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c @@ -5,18 +5,34 @@ Copyright (C) 2013, Red Hat, Inc. Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
(C) Copyright 2015 Hewlett Packard Enterprise Development LP
+Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ =20 #include "Variable.h" =20 +#include +#include + +EFI_STATUS +EFIAPI +ProtocolIsVariablePolicyEnabled ( + OUT BOOLEAN *State + ); + EFI_HANDLE mHandle =3D NULL; EFI_EVENT mVirtualAddressChangeEvent =3D NULL; VOID *mFtwRegistration =3D NULL; VOID ***mVarCheckAddressPointer =3D NULL; UINTN mVarCheckAddressPointerCount =3D 0; EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock =3D { Varia= bleLockRequestToLock }; +EDKII_VARIABLE_POLICY_PROTOCOL mVariablePolicyProtocol =3D { EDKII= _VARIABLE_POLICY_PROTOCOL_REVISION, + Disabl= eVariablePolicy, + Protoc= olIsVariablePolicyEnabled, + Regist= erVariablePolicy, + DumpVa= riablePolicy, + LockVa= riablePolicy }; EDKII_VAR_CHECK_PROTOCOL mVarCheck =3D { VarCh= eckRegisterSetVariableCheckHandler, VarChe= ckVariablePropertySet, VarChe= ckVariablePropertyGet }; @@ -282,8 +298,13 @@ OnReadyToBoot ( VOID *Context ) { + EFI_STATUS Status; + if (!mEndOfDxe) { MorLockInitAtEndOfDxe (); + + Status =3D LockVariablePolicy (); + ASSERT_EFI_ERROR (Status); // // Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID = event is not signaled. // @@ -322,8 +343,12 @@ OnEndOfDxe ( VOID *Context ) { + EFI_STATUS Status; + DEBUG ((EFI_D_INFO, "[Variable]END_OF_DXE is signaled\n")); MorLockInitAtEndOfDxe (); + Status =3D LockVariablePolicy (); + ASSERT_EFI_ERROR (Status); mEndOfDxe =3D TRUE; mVarCheckAddressPointer =3D VarCheckLibInitializeAtEndOfDxe (&mVarCheckA= ddressPointerCount); // @@ -466,6 +491,28 @@ FtwNotificationEvent ( } =20 =20 +/** + This API function returns whether or not the policy engine is + currently being enforced. + + @param[out] State Pointer to a return value for whether the poli= cy enforcement + is currently enabled. + + @retval EFI_SUCCESS + @retval Others An error has prevented this command from compl= eting. + +**/ +EFI_STATUS +EFIAPI +ProtocolIsVariablePolicyEnabled ( + OUT BOOLEAN *State + ) +{ + *State =3D IsVariablePolicyEnabled (); + return EFI_SUCCESS; +} + + /** Variable Driver main entry point. The Variable driver places the 4 EFI runtime services in the EFI System Table and installs arch protocols @@ -576,6 +623,19 @@ VariableServiceInitialize ( ); ASSERT_EFI_ERROR (Status); =20 + // Register and initialize the VariablePolicy engine. + Status =3D InitVariablePolicyLib (VariableServiceGetVariable); + ASSERT_EFI_ERROR (Status); + Status =3D VarCheckRegisterSetVariableCheckHandler (ValidateSetVariable); + ASSERT_EFI_ERROR (Status); + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &mHandle, + &gEdkiiVariablePolicyProtocolGuid, + &mVariablePolicyProtocol, + NULL + ); + ASSERT_EFI_ERROR (Status); + return EFI_SUCCESS; } =20 diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDx= e.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c new file mode 100644 index 000000000000..6ae69dffe025 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c @@ -0,0 +1,573 @@ +/** @file -- VariablePolicySmmDxe.c +This protocol allows communication with Variable Policy Engine. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "Variable.h" + +EDKII_VARIABLE_POLICY_PROTOCOL mVariablePolicyProtocol; +EFI_MM_COMMUNICATION2_PROTOCOL *mMmCommunication; + +VOID *mMmCommunicationBuffer; +UINTN mMmCommunicationBufferSize; +EFI_LOCK mMmCommunicationLock; + +/** + Internal helper function to consolidate communication method. + + @param[in,out] CommBuffer + @param[in,out] CommSize Size of the CommBuffer. + + @retval EFI_STATUS Result from communication method. + +**/ +STATIC +EFI_STATUS +InternalMmCommunicate ( + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommSize + ) +{ + EFI_STATUS Status; + if (CommBuffer =3D=3D NULL || CommSize =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + Status =3D mMmCommunication->Communicate (mMmCommunication, CommBuffer, = CommBuffer, CommSize); + return Status; +} + + +/** + This API function disables the variable policy enforcement. If it's + already been called once, will return EFI_ALREADY_STARTED. + + @retval EFI_SUCCESS + @retval EFI_ALREADY_STARTED Has already been called once this boot. + @retval EFI_WRITE_PROTECTED Interface has been locked until reboot. + @retval EFI_WRITE_PROTECTED Interface option is disabled by platfo= rm PCD. + +**/ +STATIC +EFI_STATUS +EFIAPI +ProtocolDisableVariablePolicy ( + VOID + ) +{ + EFI_STATUS Status; + EFI_MM_COMMUNICATE_HEADER *CommHeader; + VAR_CHECK_POLICY_COMM_HEADER *PolicyHeader; + UINTN BufferSize; + + // Check the PCD for convenience. + // This would also be rejected by the lib, but why go to MM if we don't = have to? + if (!PcdGetBool (PcdAllowVariablePolicyEnforcementDisable)) { + return EFI_WRITE_PROTECTED; + } + + AcquireLockOnlyAtBootTime (&mMmCommunicationLock); + + // Set up the MM communication. + BufferSize =3D mMmCommunicationBufferSize; + CommHeader =3D mMmCommunicationBuffer; + PolicyHeader =3D (VAR_CHECK_POLICY_COMM_HEADER*)&CommHeader->Data; + CopyGuid( &CommHeader->HeaderGuid, &gVarCheckPolicyLibMmiHandlerGuid ); + CommHeader->MessageLength =3D BufferSize; + PolicyHeader->Signature =3D VAR_CHECK_POLICY_COMM_SIG; + PolicyHeader->Revision =3D VAR_CHECK_POLICY_COMM_REVISION; + PolicyHeader->Command =3D VAR_CHECK_POLICY_COMMAND_DISABLE; + + Status =3D InternalMmCommunicate (CommHeader, &BufferSize); + DEBUG(( DEBUG_VERBOSE, "%a - MmCommunication returned %r.\n", __FUNCTION= __, Status )); + + ReleaseLockOnlyAtBootTime (&mMmCommunicationLock); + + return (EFI_ERROR( Status )) ? Status : PolicyHeader->Result; +} + + +/** + This API function returns whether or not the policy engine is + currently being enforced. + + @param[out] State Pointer to a return value for whether the poli= cy enforcement + is currently enabled. + + @retval EFI_SUCCESS + @retval Others An error has prevented this command from compl= eting. + +**/ +STATIC +EFI_STATUS +EFIAPI +ProtocolIsVariablePolicyEnabled ( + OUT BOOLEAN *State + ) +{ + EFI_STATUS Status; + EFI_MM_COMMUNICATE_HEADER *CommHeader; + VAR_CHECK_POLICY_COMM_HEADER *PolicyHeader; + VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS *CommandParams; + UINTN BufferSize; + + if (State =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + AcquireLockOnlyAtBootTime (&mMmCommunicationLock); + + // Set up the MM communication. + BufferSize =3D mMmCommunicationBufferSize; + CommHeader =3D mMmCommunicationBuffer; + PolicyHeader =3D (VAR_CHECK_POLICY_COMM_HEADER*)&CommHeader->Data; + CommandParams =3D (VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS*)(PolicyHeade= r + 1); + CopyGuid( &CommHeader->HeaderGuid, &gVarCheckPolicyLibMmiHandlerGuid ); + CommHeader->MessageLength =3D BufferSize; + PolicyHeader->Signature =3D VAR_CHECK_POLICY_COMM_SIG; + PolicyHeader->Revision =3D VAR_CHECK_POLICY_COMM_REVISION; + PolicyHeader->Command =3D VAR_CHECK_POLICY_COMMAND_IS_ENABLED; + + Status =3D InternalMmCommunicate (CommHeader, &BufferSize); + DEBUG(( DEBUG_VERBOSE, "%a - MmCommunication returned %r.\n", __FUNCTION= __, Status )); + + if (!EFI_ERROR( Status )) { + Status =3D PolicyHeader->Result; + *State =3D CommandParams->State; + } + + ReleaseLockOnlyAtBootTime (&mMmCommunicationLock); + + return Status; +} + + +/** + This API function validates and registers a new policy with + the policy enforcement engine. + + @param[in] NewPolicy Pointer to the incoming policy structure. + + @retval EFI_SUCCESS + @retval EFI_INVALID_PARAMETER NewPolicy is NULL or is internally i= nconsistent. + @retval EFI_ALREADY_STARTED An identical matching policy already= exists. + @retval EFI_WRITE_PROTECTED The interface has been locked until = the next reboot. + @retval EFI_UNSUPPORTED Policy enforcement has been disabled= . No reason to add more policies. + @retval EFI_ABORTED A calculation error has prevented th= is function from completing. + @retval EFI_OUT_OF_RESOURCES Cannot grow the table to hold any mo= re policies. + +**/ +STATIC +EFI_STATUS +EFIAPI +ProtocolRegisterVariablePolicy ( + IN CONST VARIABLE_POLICY_ENTRY *NewPolicy + ) +{ + EFI_STATUS Status; + EFI_MM_COMMUNICATE_HEADER *CommHeader; + VAR_CHECK_POLICY_COMM_HEADER *PolicyHeader; + VOID *PolicyBuffer; + UINTN BufferSize; + UINTN RequiredSize; + + if (NewPolicy =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // First, make sure that the required size does not exceed the capabilit= ies + // of the MmCommunication buffer. + RequiredSize =3D OFFSET_OF(EFI_MM_COMMUNICATE_HEADER, Data) + sizeof(VAR= _CHECK_POLICY_COMM_HEADER); + Status =3D SafeUintnAdd( RequiredSize, NewPolicy->Size, &RequiredSize ); + if (EFI_ERROR( Status ) || RequiredSize > mMmCommunicationBufferSize) { + DEBUG(( DEBUG_ERROR, "%a - Policy too large for buffer! %r, %d > %d \n= ", __FUNCTION__, + Status, RequiredSize, mMmCommunicationBufferSize )); + return EFI_OUT_OF_RESOURCES; + } + + AcquireLockOnlyAtBootTime (&mMmCommunicationLock); + + // Set up the MM communication. + BufferSize =3D mMmCommunicationBufferSize; + CommHeader =3D mMmCommunicationBuffer; + PolicyHeader =3D (VAR_CHECK_POLICY_COMM_HEADER*)&CommHeader->Data; + PolicyBuffer =3D (VOID*)(PolicyHeader + 1); + CopyGuid( &CommHeader->HeaderGuid, &gVarCheckPolicyLibMmiHandlerGuid ); + CommHeader->MessageLength =3D BufferSize; + PolicyHeader->Signature =3D VAR_CHECK_POLICY_COMM_SIG; + PolicyHeader->Revision =3D VAR_CHECK_POLICY_COMM_REVISION; + PolicyHeader->Command =3D VAR_CHECK_POLICY_COMMAND_REGISTER; + + // Copy the policy into place. This copy is safe because we've already t= ested above. + CopyMem( PolicyBuffer, NewPolicy, NewPolicy->Size ); + + Status =3D InternalMmCommunicate (CommHeader, &BufferSize); + DEBUG(( DEBUG_VERBOSE, "%a - MmCommunication returned %r.\n", __FUNCTION= __, Status )); + + ReleaseLockOnlyAtBootTime (&mMmCommunicationLock); + + return (EFI_ERROR( Status )) ? Status : PolicyHeader->Result; +} + + +/** + This helper function takes care of the overhead of formatting, sending, = and interpreting + the results for a single DumpVariablePolicy request. + + @param[in] PageRequested The page of the paginated results from M= M. 0 for metadata. + @param[out] TotalSize The total size of the entire buffer. Ret= urned as part of metadata. + @param[out] PageSize The size of the current page being retur= ned. Not valid as part of metadata. + @param[out] HasMore A flag indicating whether there are more= pages after this one. + @param[out] Buffer The start of the current page from MM. + + @retval EFI_SUCCESS Output params have been updated (eit= her metadata or dump page). + @retval EFI_INVALID_PARAMETER One of the output params is NULL. + @retval Others Response from MM handler. + +**/ +STATIC +EFI_STATUS +DumpVariablePolicyHelper ( + IN UINT32 PageRequested, + OUT UINT32 *TotalSize, + OUT UINT32 *PageSize, + OUT BOOLEAN *HasMore, + OUT UINT8 **Buffer + ) +{ + EFI_STATUS Status; + EFI_MM_COMMUNICATE_HEADER *CommHeader; + VAR_CHECK_POLICY_COMM_HEADER *PolicyHeader; + VAR_CHECK_POLICY_COMM_DUMP_PARAMS *CommandParams; + UINTN BufferSize; + + if (TotalSize =3D=3D NULL || PageSize =3D=3D NULL || HasMore =3D=3D NULL= || Buffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // Set up the MM communication. + BufferSize =3D mMmCommunicationBufferSize; + CommHeader =3D mMmCommunicationBuffer; + PolicyHeader =3D (VAR_CHECK_POLICY_COMM_HEADER*)&CommHeader->Data; + CommandParams =3D (VAR_CHECK_POLICY_COMM_DUMP_PARAMS*)(PolicyHeader + 1); + CopyGuid( &CommHeader->HeaderGuid, &gVarCheckPolicyLibMmiHandlerGuid ); + CommHeader->MessageLength =3D BufferSize; + PolicyHeader->Signature =3D VAR_CHECK_POLICY_COMM_SIG; + PolicyHeader->Revision =3D VAR_CHECK_POLICY_COMM_REVISION; + PolicyHeader->Command =3D VAR_CHECK_POLICY_COMMAND_DUMP; + + CommandParams->PageRequested =3D PageRequested; + + Status =3D InternalMmCommunicate (CommHeader, &BufferSize); + DEBUG(( DEBUG_VERBOSE, "%a - MmCommunication returned %r.\n", __FUNCTION= __, Status )); + + if (!EFI_ERROR( Status )) { + Status =3D PolicyHeader->Result; + *TotalSize =3D CommandParams->TotalSize; + *PageSize =3D CommandParams->PageSize; + *HasMore =3D CommandParams->HasMore; + *Buffer =3D (UINT8*)(CommandParams + 1); + } + + return Status; +} + + +/** + This API function will dump the entire contents of the variable policy t= able. + + Similar to GetVariable, the first call can be made with a 0 size and it = will return + the size of the buffer required to hold the entire table. + + @param[out] Policy Pointer to the policy buffer. Can be NULL if Siz= e is 0. + @param[in,out] Size On input, the size of the output buffer. On outp= ut, the size + of the data returned. + + @retval EFI_SUCCESS Policy data is in the output buffer = and Size has been updated. + @retval EFI_INVALID_PARAMETER Size is NULL, or Size is non-zero an= d Policy is NULL. + @retval EFI_BUFFER_TOO_SMALL Size is insufficient to hold policy.= Size updated with required size. + +**/ +STATIC +EFI_STATUS +EFIAPI +ProtocolDumpVariablePolicy ( + OUT UINT8 *Policy OPTIONAL, + IN OUT UINT32 *Size + ) +{ + EFI_STATUS Status; + UINT8 *Source; + UINT8 *Destination; + UINT32 PolicySize; + UINT32 PageSize; + BOOLEAN HasMore; + UINT32 PageIndex; + + if (Size =3D=3D NULL || (*Size > 0 && Policy =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + AcquireLockOnlyAtBootTime (&mMmCommunicationLock); + + // Repeat this whole process until we either have a failure case or get = the entire buffer. + do { + // First, we must check the zero page to determine the buffer size and + // reset the internal state. + PolicySize =3D 0; + PageSize =3D 0; + HasMore =3D FALSE; + Status =3D DumpVariablePolicyHelper (0, &PolicySize, &PageSize, &HasMo= re, &Source); + if (EFI_ERROR (Status)) { + break; + } + + // If we're good, we can at least check the required size now. + if (*Size < PolicySize) { + *Size =3D PolicySize; + Status =3D EFI_BUFFER_TOO_SMALL; + break; + } + + // On further thought, let's update the size either way. + *Size =3D PolicySize; + // And get ready to ROCK. + Destination =3D Policy; + + // Keep looping and copying until we're either done or freak out. + for (PageIndex =3D 1; !EFI_ERROR (Status) && HasMore && PageIndex < MA= X_UINT32; PageIndex++) { + Status =3D DumpVariablePolicyHelper (PageIndex, &PolicySize, &PageSi= ze, &HasMore, &Source); + if (!EFI_ERROR (Status)) { + CopyMem (Destination, Source, PageSize); + Destination +=3D PageSize; + } + } + + // Next, we check to see whether + } while (Status =3D=3D EFI_TIMEOUT); + + ReleaseLockOnlyAtBootTime (&mMmCommunicationLock); + + // There's currently no use for this, but it shouldn't be hard to implem= ent. + return Status; +} + + +/** + This API function locks the interface so that no more policy updates + can be performed or changes made to the enforcement until the next boot. + + @retval EFI_SUCCESS + @retval Others An error has prevented this command from compl= eting. + +**/ +STATIC +EFI_STATUS +EFIAPI +ProtocolLockVariablePolicy ( + VOID + ) +{ + EFI_STATUS Status; + EFI_MM_COMMUNICATE_HEADER *CommHeader; + VAR_CHECK_POLICY_COMM_HEADER *PolicyHeader; + UINTN BufferSize; + + AcquireLockOnlyAtBootTime (&mMmCommunicationLock); + + // Set up the MM communication. + BufferSize =3D mMmCommunicationBufferSize; + CommHeader =3D mMmCommunicationBuffer; + PolicyHeader =3D (VAR_CHECK_POLICY_COMM_HEADER*)&CommHeader->Data; + CopyGuid( &CommHeader->HeaderGuid, &gVarCheckPolicyLibMmiHandlerGuid ); + CommHeader->MessageLength =3D BufferSize; + PolicyHeader->Signature =3D VAR_CHECK_POLICY_COMM_SIG; + PolicyHeader->Revision =3D VAR_CHECK_POLICY_COMM_REVISION; + PolicyHeader->Command =3D VAR_CHECK_POLICY_COMMAND_LOCK; + + Status =3D InternalMmCommunicate (CommHeader, &BufferSize); + DEBUG(( DEBUG_VERBOSE, "%a - MmCommunication returned %r.\n", __FUNCTION= __, Status )); + + ReleaseLockOnlyAtBootTime (&mMmCommunicationLock); + + return (EFI_ERROR( Status )) ? Status : PolicyHeader->Result; +} + + +/** + This helper function locates the shared comm buffer and assigns it to in= put pointers. + + @param[in,out] BufferSize On input, the minimum buffer size requir= ed INCLUDING the MM communicate header. + On output, the size of the matching buff= er found. + @param[out] LocatedBuffer A pointer to the matching buffer. + + @retval EFI_SUCCESS + @retval EFI_INVALID_PARAMETER One of the output pointers was NULL. + @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate a comm= buffer. + +**/ +STATIC +EFI_STATUS +InitMmCommonCommBuffer ( + IN OUT UINTN *BufferSize, + OUT VOID **LocatedBuffer + ) +{ + EFI_STATUS Status; + + Status =3D EFI_SUCCESS; + + // Make sure that we're working with good pointers. + if (BufferSize =3D=3D NULL || LocatedBuffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // Allocate the runtime memory for the comm buffer. + *LocatedBuffer =3D AllocateRuntimePool (*BufferSize); + if (*LocatedBuffer =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + *BufferSize =3D 0; + } + + EfiInitializeLock (&mMmCommunicationLock, TPL_NOTIFY); + + return Status; +} + + +/** + Convert internal pointer addresses to virtual addresses. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context The pointer to the notification function's context= , which + is implementation-dependent. +**/ +STATIC +VOID +EFIAPI +VariablePolicyVirtualAddressCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EfiConvertPointer (0, (VOID **)&mMmCommunication); + EfiConvertPointer (0, (VOID **)&mMmCommunicationBuffer); +} + + +/** + The driver's entry point. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point executed successfully. + @retval other Some error occured when executing this entry poi= nt. + +**/ +EFI_STATUS +EFIAPI +VariablePolicySmmDxeMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + BOOLEAN ProtocolInstalled; + BOOLEAN VirtualAddressChangeRegistered; + EFI_EVENT VirtualAddressChangeEvent; + + Status =3D EFI_SUCCESS; + ProtocolInstalled =3D FALSE; + VirtualAddressChangeRegistered =3D FALSE; + + // Update the minimum buffer size. + mMmCommunicationBufferSize =3D VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE; + // Locate the shared comm buffer to use for sending MM commands. + Status =3D InitMmCommonCommBuffer( &mMmCommunicationBufferSize, &mMmComm= unicationBuffer ); + if (EFI_ERROR( Status )) { + DEBUG((DEBUG_ERROR, "%a - Failed to locate a viable MM comm buffer! %r= \n", __FUNCTION__, Status)); + ASSERT_EFI_ERROR( Status ); + return Status; + } + + // Locate the MmCommunication protocol. + Status =3D gBS->LocateProtocol( &gEfiMmCommunication2ProtocolGuid, NULL,= (VOID**)&mMmCommunication ); + if (EFI_ERROR( Status )) { + DEBUG((DEBUG_ERROR, "%a - Failed to locate MmCommunication protocol! %= r\n", __FUNCTION__, Status)); + ASSERT_EFI_ERROR( Status ); + return Status; + } + + // Configure the VariablePolicy protocol structure. + mVariablePolicyProtocol.Revision =3D EDKII_VARIABLE_POLIC= Y_PROTOCOL_REVISION; + mVariablePolicyProtocol.DisableVariablePolicy =3D ProtocolDisableVaria= blePolicy; + mVariablePolicyProtocol.IsVariablePolicyEnabled =3D ProtocolIsVariablePo= licyEnabled; + mVariablePolicyProtocol.RegisterVariablePolicy =3D ProtocolRegisterVari= ablePolicy; + mVariablePolicyProtocol.DumpVariablePolicy =3D ProtocolDumpVariable= Policy; + mVariablePolicyProtocol.LockVariablePolicy =3D ProtocolLockVariable= Policy; + + // Register all the protocols and return the status. + Status =3D gBS->InstallMultipleProtocolInterfaces( &ImageHandle, + &gEdkiiVariablePolicyPr= otocolGuid, &mVariablePolicyProtocol, + NULL ); + if (EFI_ERROR( Status )) { + DEBUG(( DEBUG_ERROR, "%a - Failed to install protocol! %r\n", __FUNCTI= ON__, Status )); + goto Exit; + } + else { + ProtocolInstalled =3D TRUE; + } + + // Normally, we might want to register a callback + // to lock the interface, but this is integrated + // into the existing callbacks in VaraiableSmm.c + // and VariableDxe.c. + + // + // Register a VirtualAddressChange callback for the MmComm protocol and = Comm buffer. + Status =3D gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + VariablePolicyVirtualAddressCallback, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &VirtualAddressChangeEvent); + if (EFI_ERROR( Status )) { + DEBUG(( DEBUG_ERROR, "%a - Failed to create VirtualAddressChange event= ! %r\n", __FUNCTION__, Status )); + goto Exit; + } + else { + VirtualAddressChangeRegistered =3D TRUE; + } + + +Exit: + // + // If we're about to return a failed status (and unload this driver), we= must first undo anything that + // has been successfully done. + if (EFI_ERROR( Status )) { + if (ProtocolInstalled) { + gBS->UninstallProtocolInterface( &ImageHandle, &gEdkiiVariablePolicy= ProtocolGuid, &mVariablePolicyProtocol ); + } + if (VirtualAddressChangeRegistered) { + gBS->CloseEvent( VirtualAddressChangeEvent ); + } + } + + return Status; +} diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c b/Mde= ModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c index caca5c32411b..014aa7985046 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c @@ -27,6 +27,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include =20 #include +#include =20 #include #include "Variable.h" @@ -689,6 +690,8 @@ SmmVariableHandler ( } if (!mEndOfDxe) { MorLockInitAtEndOfDxe (); + Status =3D LockVariablePolicy (); + ASSERT_EFI_ERROR (Status); mEndOfDxe =3D TRUE; VarCheckLibInitializeAtEndOfDxe (NULL); // @@ -974,8 +977,12 @@ SmmEndOfDxeCallback ( IN EFI_HANDLE Handle ) { + EFI_STATUS Status; + DEBUG ((EFI_D_INFO, "[Variable]SMM_END_OF_DXE is signaled\n")); MorLockInitAtEndOfDxe (); + Status =3D LockVariablePolicy (); + ASSERT_EFI_ERROR (Status); mEndOfDxe =3D TRUE; VarCheckLibInitializeAtEndOfDxe (NULL); // diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeD= xe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c index 663a1aaa128f..c47e614d81f4 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c @@ -65,6 +65,17 @@ EFI_LOCK mVariableServicesLock; EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock; EDKII_VAR_CHECK_PROTOCOL mVarCheck; =20 +/** + The logic to initialize the VariablePolicy engine is in its own file. + +**/ +EFI_STATUS +EFIAPI +VariablePolicySmmDxeMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + /** Some Secure Boot Policy Variable may update following other variable cha= nges(SecureBoot follows PK change, etc). Record their initial State when variable write service is ready. @@ -1796,6 +1807,9 @@ VariableSmmRuntimeInitialize ( &mVirtualAddressChangeEvent ); =20 + // Initialize the VariablePolicy protocol and engine. + VariablePolicySmmDxeMain (ImageHandle, SystemTable); + return EFI_SUCCESS; } =20 diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.= inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf index ceea5d1ff9ac..48ac167906f7 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf @@ -10,6 +10,7 @@ # buffer overflow or integer overflow. # # Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -69,6 +70,7 @@ [LibraryClasses] TpmMeasurementLib AuthVariableLib VarCheckLib + VariablePolicyLib =20 [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## CONSUMES diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf b/M= deModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf index bc3033588d40..bbc8d2080193 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf @@ -19,6 +19,7 @@ # the authentication service provided in this driver will be broken, and = the behavior is undefined. # # Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -78,6 +79,8 @@ [LibraryClasses] AuthVariableLib VarCheckLib UefiBootServicesTableLib + VariablePolicyLib + VariablePolicyHelperLib =20 [Protocols] gEfiSmmFirmwareVolumeBlockProtocolGuid ## CONSUMES diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeD= xe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.i= nf index 01564e4c5068..b6dbc839e023 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf @@ -14,6 +14,7 @@ # the authentication service provided in this driver will be broken, and = the behavior is undefined. # # Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -42,6 +43,7 @@ [Sources] VariableParsing.c VariableParsing.h Variable.h + VariablePolicySmmDxe.c =20 [Packages] MdePkg/MdePkg.dec @@ -56,6 +58,8 @@ [LibraryClasses] DxeServicesTableLib UefiDriverEntryPoint TpmMeasurementLib + SafeIntLib + PcdLib =20 [Protocols] gEfiVariableWriteArchProtocolGuid ## PRODUCES @@ -67,11 +71,15 @@ [Protocols] gEfiSmmVariableProtocolGuid gEdkiiVariableLockProtocolGuid ## PRODUCES gEdkiiVarCheckProtocolGuid ## PRODUCES + gEdkiiVariablePolicyProtocolGuid ## PRODUCES =20 [FeaturePcd] gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache #= # CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics #= # CONSUMES =20 +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDisable = ## CONSUMES + [Guids] ## PRODUCES ## GUID # Signature of Variable store header ## CONSUMES ## GUID # Signature of Variable store header @@ -99,6 +107,9 @@ [Guids] ## SOMETIMES_CONSUMES ## Variable:L"dbt" gEfiImageSecurityDatabaseGuid =20 + gVarCheckPolicyLibMmiHandlerGuid + gEfiEndOfDxeEventGroupGuid + [Depex] gEfiMmCommunication2ProtocolGuid =20 --=20 2.28.0.windows.1 -=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 (#67155): https://edk2.groups.io/g/devel/message/67155 Mute This Topic: https://groups.io/mt/78130779/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 Tue Apr 30 19:24:51 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+67156+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+67156+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1604904403; cv=none; d=zohomail.com; s=zohoarc; b=BZ6Svn5OH13q+Hluvl3o3hyXKp78uFA4J3Q1nrtf0pxIddbqZI3tK+UMK3nmbCexdr21yRaiIG0JAPqQeEfWNiKI31nGKLPmhPMYKfyi/zPaHYek3Dyh2Xb6vC9fBRYJf7yh1HMypML6PS32TTyVlLqR8SXBekLURlUGgYaWnM8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604904403; 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=FQof/DzdeZQM2ktI7ssVuQ9jUbSTR4Me9sqBKJUlhcI=; b=gz/IC3mYsxdceX9DxnVVyDThFUDxdy/jQcoGGOlblEu7CVgCKiQkbanecJwC84r4E0FmCnoj4MwmbVmVU1ASdGo52t10jvFSuyuU8gYio0L3bJYeeGUuxUad0Hela6zO6g7z9NkNd1j7VzPKfNJFuIynzc9m22Bz8kMi7kSgGw0= 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+67156+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604904403051390.95451322315637; Sun, 8 Nov 2020 22:46:43 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 9tbgYY1788612xVOXTdl9zdk; Sun, 08 Nov 2020 22:46:42 -0800 X-Received: from mail-pg1-f193.google.com (mail-pg1-f193.google.com [209.85.215.193]) by mx.groups.io with SMTP id smtpd.web11.8063.1604904402364531418 for ; Sun, 08 Nov 2020 22:46:42 -0800 X-Received: by mail-pg1-f193.google.com with SMTP id w4so6275841pgg.13 for ; Sun, 08 Nov 2020 22:46:42 -0800 (PST) X-Gm-Message-State: 7pSouPRSTRLG3lMkv6tcyXxyx1787277AA= X-Google-Smtp-Source: ABdhPJylSg/WCzE4Kd/1FmDUydosCZYTBWn7dBGwWjkVHaTUeWTXYpVTrjdqAXsRq8ucHqIWRjD6og== X-Received: by 2002:aa7:870e:0:b029:18b:f46:9ca9 with SMTP id b14-20020aa7870e0000b029018b0f469ca9mr12418832pfo.3.1604904401719; Sun, 08 Nov 2020 22:46:41 -0800 (PST) X-Received: from localhost.localdomain ([71.212.128.184]) by smtp.gmail.com with ESMTPSA id s145sm10215111pfs.187.2020.11.08.22.46.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Nov 2020 22:46:41 -0800 (PST) From: "Bret Barkelew" X-Google-Original-From: Bret Barkelew To: devel@edk2.groups.io Cc: Jian J Wang , Hao A Wu , Liming Gao , Bret Barkelew , Dandan Bi Subject: [edk2-devel] [PATCH v9 10/13] MdeModulePkg: Allow VariablePolicy state to delete protected variables Date: Sun, 8 Nov 2020 22:45:19 -0800 Message-Id: <20201109064522.919-11-bret.barkelew@microsoft.com> In-Reply-To: <20201109064522.919-1-bret.barkelew@microsoft.com> References: <20201109064522.919-1-bret.barkelew@microsoft.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,bret@corthon.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604904402; bh=ibgiJdn8/3Gx9mUnliMUPsm+qu7E0NJ2kvXlOgMYyJk=; h=Cc:Date:From:Reply-To:Subject:To; b=bsx9haTC8h0GcD5SQqGrwIgtjpmmKFhnBKVXUCuewmHuwBmkCA8Z+7VlJE418TrAI1V 2gjqxZ+M7t6sPgBItlcHiDOeU/kVsqH32Eu15xM85BDlsUlGPB5FTOqtdYrtAppWQlbVK FBHItghAyrp4XpyOSp65yG7EhsaxUY87gyo= 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=3D2522 TcgMorLockSmm provides special protections for the TCG MOR variables. This will check IsVariablePolicyEnabled() before enforcing them to allow variable deletion when policy engine is disabled. Only allows deletion, not modification. Cc: Jian J Wang Cc: Hao A Wu Cc: Liming Gao Cc: Bret Barkelew Signed-off-by: Bret Barkelew Reviewed-by: Dandan Bi Acked-by: Jian J Wang --- MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c | 10 += +++++++++ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf | 2 ++ 2 files changed, 12 insertions(+) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c b/M= deModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c index 6d80eb64341a..085f82035f4b 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c @@ -5,6 +5,7 @@ This module adds Variable Hook and check MemoryOverwriteRequestControlLo= ck. =20 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ @@ -17,6 +18,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include "Variable.h" =20 +#include + +#include + typedef struct { CHAR16 *VariableName; EFI_GUID *VendorGuid; @@ -341,6 +346,11 @@ SetVariableCheckHandlerMor ( return EFI_SUCCESS; } =20 + // Permit deletion when policy is disabled. + if (!IsVariablePolicyEnabled() && ((Attributes =3D=3D 0) || (DataSize = =3D=3D 0))) { + return EFI_SUCCESS; + } + // // MorLock variable // diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneM= m.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf index 6e17f6cdf588..d8f480be27cc 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf @@ -20,6 +20,7 @@ # # Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
# Copyright (c) 2018, Linaro, Ltd. All rights reserved.
+# Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -74,6 +75,7 @@ [LibraryClasses] StandaloneMmDriverEntryPoint SynchronizationLib VarCheckLib + VariablePolicyLib =20 [Protocols] gEfiSmmFirmwareVolumeBlockProtocolGuid ## CONSUMES --=20 2.28.0.windows.1 -=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 (#67156): https://edk2.groups.io/g/devel/message/67156 Mute This Topic: https://groups.io/mt/78130780/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 Tue Apr 30 19:24:51 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+67157+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+67157+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1604904409; cv=none; d=zohomail.com; s=zohoarc; b=ilre9XnrogOc6kNtNJCpft3fa769cuJmCvoQFvj4susrHI9VzpuCT5Jbf+9LcW2xkwy00l/UYa3pjoLLHjgRZDzneeSGl4fufXSJ//96GCxxPjLgCRo3tQaokRra2+xXI9xiLrg/XZqvdN2x6jjyaOKDPE7SwXN70l9aytLV27Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604904409; 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=vV2xWcglqRexXbgZJwnmc6/Gky+PVinmjjXlJCdIEOE=; b=d5kRt2NmpgDMZPzJ+owE8EQUPKgG+PoCRDFEjKsbhMPlScUqPexrRCAzDkzeqgyqcU8nQMluhFOvaCRVCQ8J4dtg0xpPu6v+I00PSB0gCGuJ0B8C5VPN9eO2nKmTwswdwN8IMLfQyaIi/6XyRQEQMQONCB5bhtB3aJJ9OW2WdIo= 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+67157+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604904409246593.1598422066945; Sun, 8 Nov 2020 22:46:49 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id ZyumYY1788612x06JmhJRxh1; Sun, 08 Nov 2020 22:46:48 -0800 X-Received: from mail-pf1-f176.google.com (mail-pf1-f176.google.com [209.85.210.176]) by mx.groups.io with SMTP id smtpd.web12.8024.1604904403460684234 for ; Sun, 08 Nov 2020 22:46:43 -0800 X-Received: by mail-pf1-f176.google.com with SMTP id c20so7191507pfr.8 for ; Sun, 08 Nov 2020 22:46:43 -0800 (PST) X-Gm-Message-State: LunxBgegYsgjy2iQPP5vsTVIx1787277AA= X-Google-Smtp-Source: ABdhPJw8hx1k5q75XcNGG0GU2ShDv77W69uicsl5Zskf0pTpG0wH0v0RYhwvf3/ieqIlUmhZ0zY/JA== X-Received: by 2002:aa7:9abb:0:b029:18b:5a1d:b729 with SMTP id x27-20020aa79abb0000b029018b5a1db729mr11997672pfi.81.1604904402654; Sun, 08 Nov 2020 22:46:42 -0800 (PST) X-Received: from localhost.localdomain ([71.212.128.184]) by smtp.gmail.com with ESMTPSA id s145sm10215111pfs.187.2020.11.08.22.46.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Nov 2020 22:46:42 -0800 (PST) From: "Bret Barkelew" X-Google-Original-From: Bret Barkelew To: devel@edk2.groups.io Cc: Jiewen Yao , Jian J Wang , Chao Zhang , Bret Barkelew , Dandan Bi Subject: [edk2-devel] [PATCH v9 11/13] SecurityPkg: Allow VariablePolicy state to delete authenticated variables Date: Sun, 8 Nov 2020 22:45:20 -0800 Message-Id: <20201109064522.919-12-bret.barkelew@microsoft.com> In-Reply-To: <20201109064522.919-1-bret.barkelew@microsoft.com> References: <20201109064522.919-1-bret.barkelew@microsoft.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,bret@corthon.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604904408; bh=SZLtV6b9VG7n2QL24uh8hiy1kY2sI1qTejzJXF7Y9pM=; h=Cc:Date:From:Reply-To:Subject:To; b=FsOVDCQQ4G2vOnQgC8cnE0Fyb1uWKUrmOsLzAPxQawTQyMIV3HR0PagZ617cXrSNex2 p+jHPrgERHKP3OYPpojk76zkQm/ZaBfBQJ2BvEzuB9h0L+qAVJh7D9DsNY+C9ZoGN+bch UwE48EW+NLaaVGGA0Kf1B2LzSKiP+ZgL8RA= 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=3D2522 Causes AuthService to check IsVariablePolicyEnabled() before enforcing write protections to allow variable deletion when policy engine is disabled. Only allows deletion, not modification. Cc: Jiewen Yao Cc: Jian J Wang Cc: Chao Zhang Cc: Bret Barkelew Signed-off-by: Bret Barkelew Reviewed-by: Dandan Bi Acked-by: Jian J Wang --- SecurityPkg/Library/AuthVariableLib/AuthService.c | 30 +++++++++++++= +++---- SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf | 2 ++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/SecurityPkg/Library/AuthVariableLib/AuthService.c b/SecurityPk= g/Library/AuthVariableLib/AuthService.c index 2f60331f2c04..4fb609504db7 100644 --- a/SecurityPkg/Library/AuthVariableLib/AuthService.c +++ b/SecurityPkg/Library/AuthVariableLib/AuthService.c @@ -19,12 +19,16 @@ to verify the signature. =20 Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ =20 #include "AuthServiceInternal.h" =20 +#include +#include + // // Public Exponent of RSA Key. // @@ -217,9 +221,12 @@ NeedPhysicallyPresent( IN EFI_GUID *VendorGuid ) { - if ((CompareGuid (VendorGuid, &gEfiSecureBootEnableDisableGuid) && (StrC= mp (VariableName, EFI_SECURE_BOOT_ENABLE_NAME) =3D=3D 0)) - || (CompareGuid (VendorGuid, &gEfiCustomModeEnableGuid) && (StrCmp (Va= riableName, EFI_CUSTOM_MODE_NAME) =3D=3D 0))) { - return TRUE; + // If the VariablePolicy engine is disabled, allow deletion of any authe= nticated variables. + if (IsVariablePolicyEnabled()) { + if ((CompareGuid (VendorGuid, &gEfiSecureBootEnableDisableGuid) && (St= rCmp (VariableName, EFI_SECURE_BOOT_ENABLE_NAME) =3D=3D 0)) + || (CompareGuid (VendorGuid, &gEfiCustomModeEnableGuid) && (StrCmp (= VariableName, EFI_CUSTOM_MODE_NAME) =3D=3D 0))) { + return TRUE; + } } =20 return FALSE; @@ -842,7 +849,8 @@ ProcessVariable ( &OrgVariableInfo ); =20 - if ((!EFI_ERROR (Status)) && IsDeleteAuthVariable (OrgVariableInfo.Attri= butes, Data, DataSize, Attributes) && UserPhysicalPresent()) { + // If the VariablePolicy engine is disabled, allow deletion of any authe= nticated variables. + if ((!EFI_ERROR (Status)) && IsDeleteAuthVariable (OrgVariableInfo.Attri= butes, Data, DataSize, Attributes) && (UserPhysicalPresent() || !IsVariable= PolicyEnabled())) { // // Allow the delete operation of common authenticated variable(AT or A= W) at user physical presence. // @@ -1920,6 +1928,12 @@ VerifyTimeBasedPayload ( PayloadPtr =3D SigData + SigDataSize; PayloadSize =3D DataSize - OFFSET_OF_AUTHINFO2_CERT_DATA - (UINTN) SigDa= taSize; =20 + // If the VariablePolicy engine is disabled, allow deletion of any authe= nticated variables. + if (PayloadSize =3D=3D 0 && (Attributes & EFI_VARIABLE_APPEND_WRITE) =3D= =3D 0 && !IsVariablePolicyEnabled()) { + VerifyStatus =3D TRUE; + goto Exit; + } + // // Construct a serialization buffer of the values of the VariableName, V= endorGuid and Attributes // parameters of the SetVariable() call and the TimeStamp component of t= he @@ -2173,8 +2187,12 @@ VerifyTimeBasedPayload ( Exit: =20 if (AuthVarType =3D=3D AuthVarTypePk || AuthVarType =3D=3D AuthVarTypePr= iv) { - Pkcs7FreeSigners (TopLevelCert); - Pkcs7FreeSigners (SignerCerts); + if (TopLevelCert !=3D NULL) { + Pkcs7FreeSigners (TopLevelCert); + } + if (SignerCerts !=3D NULL) { + Pkcs7FreeSigners (SignerCerts); + } } =20 if (!VerifyStatus) { diff --git a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf b/Secu= rityPkg/Library/AuthVariableLib/AuthVariableLib.inf index 8d4ce14df494..8eadeebcebd7 100644 --- a/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf +++ b/SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf @@ -3,6 +3,7 @@ # # Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
# Copyright (c) 2018, ARM Limited. All rights reserved.
+# Copyright (c) Microsoft Corporation. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -41,6 +42,7 @@ [LibraryClasses] MemoryAllocationLib BaseCryptLib PlatformSecureLib + VariablePolicyLib =20 [Guids] ## CONSUMES ## Variable:L"SetupMode" --=20 2.28.0.windows.1 -=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 (#67157): https://edk2.groups.io/g/devel/message/67157 Mute This Topic: https://groups.io/mt/78130781/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 Tue Apr 30 19:24:51 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+67158+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+67158+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1604904405; cv=none; d=zohomail.com; s=zohoarc; b=Rmgx5qq/ttIvvNNLt5lGx3ML0DErh1B9BzDfXe/YOkf25bFjvho1tM4N3pSXLH+tzhx1ojnc5und8zQjqBUrw5E56eXo8xj4UUR3UoSEjelNsZWRnEIubRLTkJTKY1NIPb2xlcLY60vVqwfT3pnQ/4jfC2vxQMR5V/MQtr4SNhM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604904405; 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=H2eW0wHFd6cUQFt0WGtqgLIpGBr3McegeNaZE23wOLU=; b=diqwA/a1p2AxZFx9y6N9fJ1c6QQyHdInFNyeePS314a8lW2p/CJ/D+VprQwF63JZZA2hXjdkdos/Zmj90txuLdR96KmHnTeuvZuzdHoJfceD24cnjSGFQGC1eCgAJImf15404h8vNsTI855pv2EI2x6KT5eWzFzCmSxuAWSqVdc= 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+67158+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604904405729229.81113713057744; Sun, 8 Nov 2020 22:46:45 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id GZVaYY1788612x6IqkUAFlUA; Sun, 08 Nov 2020 22:46:45 -0800 X-Received: from mail-pf1-f195.google.com (mail-pf1-f195.google.com [209.85.210.195]) by mx.groups.io with SMTP id smtpd.web12.8025.1604904404960429172 for ; Sun, 08 Nov 2020 22:46:45 -0800 X-Received: by mail-pf1-f195.google.com with SMTP id c20so7191568pfr.8 for ; Sun, 08 Nov 2020 22:46:44 -0800 (PST) X-Gm-Message-State: 7NfqbV5PwCT0oElPeRVcjuSex1787277AA= X-Google-Smtp-Source: ABdhPJzBWqTejCd9x+P2Dl0pvlcrbdyjCQM2ZONBXTD9wa/xY19gzhd/KRymyXK4jSgssXCSX6EFwA== X-Received: by 2002:a62:2a8a:0:b029:18b:83c1:60af with SMTP id q132-20020a622a8a0000b029018b83c160afmr12694080pfq.54.1604904404248; Sun, 08 Nov 2020 22:46:44 -0800 (PST) X-Received: from localhost.localdomain ([71.212.128.184]) by smtp.gmail.com with ESMTPSA id s145sm10215111pfs.187.2020.11.08.22.46.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Nov 2020 22:46:43 -0800 (PST) From: "Bret Barkelew" X-Google-Original-From: Bret Barkelew To: devel@edk2.groups.io Cc: Jian J Wang , Hao A Wu , Liming Gao , Bret Barkelew , Dandan Bi Subject: [edk2-devel] [PATCH v9 12/13] MdeModulePkg: Change TCG MOR variables to use VariablePolicy Date: Sun, 8 Nov 2020 22:45:21 -0800 Message-Id: <20201109064522.919-13-bret.barkelew@microsoft.com> In-Reply-To: <20201109064522.919-1-bret.barkelew@microsoft.com> References: <20201109064522.919-1-bret.barkelew@microsoft.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,bret@corthon.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604904405; bh=Xe3ir83MCChWeKZQonEyOxcuafhBQpGld/Nx2zdgG+Q=; h=Cc:Date:From:Reply-To:Subject:To; b=nOHeyU/f8S4hzIag5gLW1wMrIW237NzR+p0ydIqjtRczlknMK2AspRa3hy9zRBB+qkh OfaYmWXWAUJTlPyirZqwR26t+mFzhTMqy3YhZFS6QwxVUWWctAQ3v2xYy184q/mqyQPpW yov5dpGahcmMxExXulGyObFxa8McyVKoHuk= 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=3D2522 These were previously using VarLock, which is being deprecated. Cc: Jian J Wang Cc: Hao A Wu Cc: Liming Gao Cc: Bret Barkelew Signed-off-by: Bret Barkelew Reviewed-by: Dandan Bi Acked-by: Jian J Wang --- MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c | 52 += +++++++++++++------ MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c | 52 += ++++++++++++++----- MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf | 2 + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf | 1 + 4 files changed, 82 insertions(+), 25 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c b/M= deModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c index e7accf4ed806..b85f08c48c11 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c @@ -5,6 +5,7 @@ MOR lock control unsupported. =20 Copyright (c) 2016, Intel Corporation. All rights reserved.
+Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ @@ -17,7 +18,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include "Variable.h" =20 -extern EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock; +#include +#include =20 /** This service is an MOR/MorLock checker handler for the SetVariable(). @@ -77,11 +79,6 @@ MorLockInit ( NULL // Data ); =20 - // - // Need set this variable to be read-only to prevent other module set it. - // - VariableLockRequestToLock (&mVariableLock, MEMORY_OVERWRITE_REQUEST_CONT= ROL_LOCK_NAME, &gEfiMemoryOverwriteRequestControlLockGuid); - // // The MOR variable can effectively improve platform security only when = the // MorLock variable protects the MOR variable. In turn MorLock cannot be= made @@ -99,11 +96,6 @@ MorLockInit ( 0, // DataSize NULL // Data ); - VariableLockRequestToLock ( - &mVariableLock, - MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, - &gEfiMemoryOverwriteControlDataGuid - ); =20 return EFI_SUCCESS; } @@ -118,7 +110,39 @@ MorLockInitAtEndOfDxe ( VOID ) { - // - // Do nothing. - // + EFI_STATUS Status; + EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy; + + // First, we obviously need to locate the VariablePolicy protocol. + Status =3D gBS->LocateProtocol( &gEdkiiVariablePolicyProtocolGuid, NULL,= (VOID**)&VariablePolicy ); + if (EFI_ERROR( Status )) { + DEBUG(( DEBUG_ERROR, "%a - Could not locate VariablePolicy protocol! %= r\n", __FUNCTION__, Status )); + return; + } + + // If we're successful, go ahead and set the policies to protect the tar= get variables. + Status =3D RegisterBasicVariablePolicy( VariablePolicy, + &gEfiMemoryOverwriteRequestControl= LockGuid, + MEMORY_OVERWRITE_REQUEST_CONTROL_L= OCK_NAME, + 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 ); + if (EFI_ERROR( Status )) { + DEBUG(( DEBUG_ERROR, "%a - Could not lock variable %s! %r\n", __FUNCTI= ON__, MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME, Status )); + } + Status =3D RegisterBasicVariablePolicy( VariablePolicy, + &gEfiMemoryOverwriteControlDataGui= d, + MEMORY_OVERWRITE_REQUEST_VARIABLE_= NAME, + 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 ); + if (EFI_ERROR( Status )) { + DEBUG(( DEBUG_ERROR, "%a - Could not lock variable %s! %r\n", __FUNCTI= ON__, MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, Status )); + } + + return; } diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c b/M= deModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c index 085f82035f4b..ee37942a6b0c 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c @@ -19,7 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "Variable.h" =20 #include - +#include #include =20 typedef struct { @@ -422,6 +422,8 @@ MorLockInitAtEndOfDxe ( { UINTN MorSize; EFI_STATUS MorStatus; + EFI_STATUS Status; + VARIABLE_POLICY_ENTRY *NewPolicy; =20 if (!mMorLockInitializationRequired) { // @@ -494,11 +496,25 @@ MorLockInitAtEndOfDxe ( // The MOR variable is absent; the platform firmware does not support it. // Lock the variable so that no other module may create it. // - VariableLockRequestToLock ( - NULL, // This - MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, - &gEfiMemoryOverwriteControlDataGuid - ); + NewPolicy =3D NULL; + Status =3D CreateBasicVariablePolicy( &gEfiMemoryOverwriteControlDataGui= d, + MEMORY_OVERWRITE_REQUEST_VARIABLE_NA= ME, + 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 ); + } + if (EFI_ERROR( Status )) { + DEBUG(( DEBUG_ERROR, "%a - Failed to lock variable %s! %r\n", __FUNCTI= ON__, MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, Status )); + ASSERT_EFI_ERROR( Status ); + } + if (NewPolicy !=3D NULL) { + FreePool( NewPolicy ); + } =20 // // Delete the MOR Control Lock variable too (should it exists for some @@ -514,9 +530,23 @@ MorLockInitAtEndOfDxe ( ); mMorLockPassThru =3D FALSE; =20 - VariableLockRequestToLock ( - NULL, // This - MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME, - &gEfiMemoryOverwriteRequestControlLockGuid - ); + NewPolicy =3D NULL; + Status =3D CreateBasicVariablePolicy( &gEfiMemoryOverwriteRequestControl= LockGuid, + MEMORY_OVERWRITE_REQUEST_CONTROL_LOC= K_NAME, + 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 ); + } + if (EFI_ERROR( Status )) { + DEBUG(( DEBUG_ERROR, "%a - Failed to lock variable %s! %r\n", __FUNCTI= ON__, MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME, Status )); + ASSERT_EFI_ERROR( Status ); + } + if (NewPolicy !=3D NULL) { + FreePool( NewPolicy ); + } } diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.= inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf index 48ac167906f7..8debc560e6dc 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf @@ -71,6 +71,7 @@ [LibraryClasses] AuthVariableLib VarCheckLib VariablePolicyLib + VariablePolicyHelperLib =20 [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## CONSUMES @@ -80,6 +81,7 @@ [Protocols] gEfiVariableWriteArchProtocolGuid ## PRODUCES gEfiVariableArchProtocolGuid ## PRODUCES gEdkiiVariableLockProtocolGuid ## PRODUCES + gEdkiiVariablePolicyProtocolGuid ## CONSUMES gEdkiiVarCheckProtocolGuid ## PRODUCES =20 [Guids] diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneM= m.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf index d8f480be27cc..62f2f9252f43 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf @@ -76,6 +76,7 @@ [LibraryClasses] SynchronizationLib VarCheckLib VariablePolicyLib + VariablePolicyHelperLib =20 [Protocols] gEfiSmmFirmwareVolumeBlockProtocolGuid ## CONSUMES --=20 2.28.0.windows.1 -=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 (#67158): https://edk2.groups.io/g/devel/message/67158 Mute This Topic: https://groups.io/mt/78130782/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 Tue Apr 30 19:24:51 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+67159+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+67159+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1604904407; cv=none; d=zohomail.com; s=zohoarc; b=PzpFFlnB+krJ9WWyEAUFggX5tdCrOG7t8huDNNuCKUYmewmZTElfAjgc2uNGvDJR4OfZbwULDGmBDBBz38eKRLqvBJopJoMfmQo3VyoSrmS3sPgopTQHruCzM3nICqYJobU8r9Tp7q3DTueM0zAVvMQhX1sKTgXkDzikSdcX39I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1604904407; 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=flwjwSFI4Npl9B/g+DnFYQ+rwZezcJyvk6MNCQjy+fs=; b=Xt62jObU5myJA2P/jGEZ0lh6VbMXrcWrTZ9ImvmI+Ec3+krY18wa1EIAtq1Ro8oURrR0Zm+8h4IezG1pBHym+nZnTHoWd04u3uIz9qQW0JaIetWGd/kY5u9QV96bckRVgFdqLQZqoWrSYBpYAuI9nSMxJHtfVPPL8bY/fvPNzi8= 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+67159+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1604904407124567.2229679819656; Sun, 8 Nov 2020 22:46:47 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id FQ72YY1788612xZDIk9UWbAq; Sun, 08 Nov 2020 22:46:46 -0800 X-Received: from mail-pf1-f174.google.com (mail-pf1-f174.google.com [209.85.210.174]) by mx.groups.io with SMTP id smtpd.web09.7971.1604904406251863871 for ; Sun, 08 Nov 2020 22:46:46 -0800 X-Received: by mail-pf1-f174.google.com with SMTP id z3so7175202pfb.10 for ; Sun, 08 Nov 2020 22:46:46 -0800 (PST) X-Gm-Message-State: 3V9XFbO7PG0LL8QmPgmmZTrMx1787277AA= X-Google-Smtp-Source: ABdhPJymQJsT337j2s/0grLCmlQA6hReLGolmqo0EKTBhGE7KqhBZ1ovhIJ7NzsGko1qWvvr+JYEnQ== X-Received: by 2002:aa7:8b0b:0:b029:152:900d:2288 with SMTP id f11-20020aa78b0b0000b0290152900d2288mr12492139pfd.53.1604904405565; Sun, 08 Nov 2020 22:46:45 -0800 (PST) X-Received: from localhost.localdomain ([71.212.128.184]) by smtp.gmail.com with ESMTPSA id s145sm10215111pfs.187.2020.11.08.22.46.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Nov 2020 22:46:44 -0800 (PST) From: "Bret Barkelew" X-Google-Original-From: Bret Barkelew To: devel@edk2.groups.io Cc: Jian J Wang , Hao A Wu , Liming Gao , Bret Barkelew , Dandan Bi Subject: [edk2-devel] [PATCH v9 13/13] MdeModulePkg: Drop VarLock from RuntimeDxe variable driver Date: Sun, 8 Nov 2020 22:45:22 -0800 Message-Id: <20201109064522.919-14-bret.barkelew@microsoft.com> In-Reply-To: <20201109064522.919-1-bret.barkelew@microsoft.com> References: <20201109064522.919-1-bret.barkelew@microsoft.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,bret@corthon.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1604904406; bh=av0cuqQNpluO1aOgRSKffr/AvjPFp09lz8RA+ilrSL4=; h=Cc:Date:From:Reply-To:Subject:To; b=qGEXdoxl2L8VIajiogTwfGeTXcNnwDVZ1XWUrN1y/AJ9CIpSbdlpfFoZsmSuWrdsFxA UTIKDaqs0ercocRdxvvtrc0cAq4bPE9J+6APVpbls+WP2ZuC+Za/y/ySF/99QW2hDyjLn 8AbsAmxZdn2/fRHSPwE1fzP0rmYAHwBGXTo= 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=3D2522 Now that everything should be moved to VariablePolicy, drop support for the deprecated VarLock SMI interface and associated functions from variable RuntimeDxe. Cc: Jian J Wang Cc: Hao A Wu Cc: Liming Gao Cc: Bret Barkelew Signed-off-by: Bret Barkelew Reviewed-by: Dandan Bi Acked-by: Jian J Wang --- MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c | 4= 9 +------------- MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequestToLock.c | 7= 1 ++++++++++++++++++++ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf | = 1 + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf | = 1 + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf | = 1 + 5 files changed, 75 insertions(+), 48 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c b/MdeMod= ulePkg/Universal/Variable/RuntimeDxe/VarCheck.c index f15219df5eb8..486d85b022e1 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c @@ -3,60 +3,13 @@ and variable lock protocol based on VarCheckLib. =20 Copyright (c) 2015, Intel Corporation. All rights reserved.
+Copyright (c) Microsoft Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ =20 #include "Variable.h" =20 -/** - 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. - - @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. - - @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. -**/ -EFI_STATUS -EFIAPI -VariableLockRequestToLock ( - IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid - ) -{ - EFI_STATUS Status; - VAR_CHECK_VARIABLE_PROPERTY Property; - - AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.Variab= leServicesLock); - - Status =3D VarCheckLibVariablePropertyGet (VariableName, VendorGuid, &Pr= operty); - if (!EFI_ERROR (Status)) { - Property.Property |=3D VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY; - } else { - Property.Revision =3D VAR_CHECK_VARIABLE_PROPERTY_REVISION; - Property.Property =3D VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY; - Property.Attributes =3D 0; - Property.MinSize =3D 1; - Property.MaxSize =3D MAX_UINTN; - } - Status =3D VarCheckLibVariablePropertySet (VariableName, VendorGuid, &Pr= operty); - - DEBUG ((EFI_D_INFO, "[Variable] Lock: %g:%s %r\n", VendorGuid, VariableN= ame, Status)); - - ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.Variab= leServicesLock); - - return Status; -} - /** Register SetVariable check handler. =20 diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequest= ToLock.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequestTo= Lock.c new file mode 100644 index 000000000000..4aa854aaf260 --- /dev/null +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableLockRequestToLock.c @@ -0,0 +1,71 @@ +/** @file -- VariableLockRequestToLock.c +Temporary location of the RequestToLock shim code while +projects are moved to VariablePolicy. Should be removed when deprecated. + +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include + +#include + +#include +#include +#include + + +/** + 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. + + @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. + + @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. +**/ +EFI_STATUS +EFIAPI +VariableLockRequestToLock ( + IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid + ) +{ + EFI_STATUS Status; + VARIABLE_POLICY_ENTRY *NewPolicy; + + 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 ); + if (!EFI_ERROR( Status )) { + Status =3D RegisterVariablePolicy( NewPolicy ); + } + 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 ); + } + + return Status; +} diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.= inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf index 8debc560e6dc..c9434df631ee 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf @@ -49,6 +49,7 @@ [Sources] VarCheck.c VariableExLib.c SpeculationBarrierDxe.c + VariableLockRequestToLock.c =20 [Packages] MdePkg/MdePkg.dec diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf b/M= deModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf index bbc8d2080193..eaa97a01c6e5 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf @@ -58,6 +58,7 @@ [Sources] VariableExLib.c TcgMorLockSmm.c SpeculationBarrierSmm.c + VariableLockRequestToLock.c =20 [Packages] MdePkg/MdePkg.dec diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneM= m.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf index 62f2f9252f43..fada0bf3c57f 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf @@ -58,6 +58,7 @@ [Sources] VariableExLib.c TcgMorLockSmm.c SpeculationBarrierSmm.c + VariableLockRequestToLock.c =20 [Packages] MdePkg/MdePkg.dec --=20 2.28.0.windows.1 -=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 (#67159): https://edk2.groups.io/g/devel/message/67159 Mute This Topic: https://groups.io/mt/78130783/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-