From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mx.groups.io with SMTP id smtpd.web11.3201.1593656000009666201 for ; Wed, 01 Jul 2020 19:13:21 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=barWohQk; spf=pass (domain: intel.com, ip: 134.134.136.20, mailfrom: dandan.bi@intel.com) IronPort-SDR: jhsyoJJqnb7FagD+/8DYO68BvdXhnA0/okBF2SqUsmVrSKlSsG1UukUhjtOSbg0yEi1S7HpKqa VSrKOlPvjUIw== X-IronPort-AV: E=McAfee;i="6000,8403,9669"; a="135055232" X-IronPort-AV: E=Sophos;i="5.75,302,1589266800"; d="scan'208";a="135055232" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Jul 2020 19:13:18 -0700 IronPort-SDR: FVXbOoD0+PYyisosGt++TFjgUBEmpjsLEVgomFGHtyCib9VWQ+75BMFgvmDwNzncid3A6FKuvx 7fphoWbMLfXg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,302,1589266800"; d="scan'208";a="295738389" Received: from fmsmsx106.amr.corp.intel.com ([10.18.124.204]) by orsmga002.jf.intel.com with ESMTP; 01 Jul 2020 19:13:18 -0700 Received: from fmsmsx115.amr.corp.intel.com (10.18.116.19) by FMSMSX106.amr.corp.intel.com (10.18.124.204) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 1 Jul 2020 19:13:18 -0700 Received: from FMSEDG002.ED.cps.intel.com (10.1.192.134) by fmsmsx115.amr.corp.intel.com (10.18.116.19) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 1 Jul 2020 19:13:18 -0700 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (104.47.55.106) by edgegateway.intel.com (192.55.55.69) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 1 Jul 2020 19:13:18 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=LTrU+w9DGlrR9VYo1clDG4vOSIF/r2kARJKB+RX613Wh8wlzW/A6WeQ9g6cxHelFfIAm1NBHKQOob6Ehd6MBTS+9+T/oHvkQlXaKryCUbdgILQaXuImOZ+xn3XE5cNB02srjSs3O1bZMMM0K6PTTS06CyEfHPuFVUQC7yytQbeiNGKM4TDXQ60Qo8FOPmhazZUCMVH2sNsfbPuCzXQcgNQgG/eNINis+8YesZchWNQA24ekNBM7RfRRx6uw+c5ID6Lk3VHOzN3a5o+l6Tcg+h9CWaK/0lSl4TIKDmpEqFVGI2OXcXgdg7p0Xy69qRjhw5nPg/Y03pwZM2XD11GG2hQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=uuOofJ8QcGrSMW/7lB71mDh/wdBMnTqHSEvN3X5ou+w=; b=I1xJQyTH+qMsJXnrXWkHWWmS9mSzvuoCbOJ55sEKOhY3xxileGGQrDK5YcjKAPT5+YDg4v0IgMJszstid/6zD9Iqj0fHt5tFuS0Oiq4XWpdrqsAWoiOiHdaU9WgbiGi+pxI+aL68dr3Mlxo8aA2UsWwV1OuFDPwDd2LDepjrH6EYdwNi1NgUyL2XY3JMSB/xeO63ZdGrxl31HBrf0RKGYT6a8vHFZoQXfYzvPEqexSIbpsOVoagbnfHQiEcI60KJs+EuSKQNaa0V64vZ1HJKIebPhaOnNL/MCB0KxypMIGnxeAz4yPu5SwpCJPlfI15Y3yxYBnVCV6h7AR2C/v1uzQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=uuOofJ8QcGrSMW/7lB71mDh/wdBMnTqHSEvN3X5ou+w=; b=barWohQkXOBauSv4YlSVgK5Zjxv2IVATRz75rokEI/qLlpLNVfEr3yDlF2nNWMy2XgBcBK+SgGImQlfyiVDx8akOCxW5VohyNz/p4zwfqcvMoaSsEBuAPgyrnFo94EtDjrF9EOSoqraKE184UBUMkeqEpjoCqHaznR1nfK88OoY= Received: from BN6PR11MB1393.namprd11.prod.outlook.com (2603:10b6:404:3c::12) by BN8PR11MB3812.namprd11.prod.outlook.com (2603:10b6:408:90::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3131.21; Thu, 2 Jul 2020 02:13:16 +0000 Received: from BN6PR11MB1393.namprd11.prod.outlook.com ([fe80::a1f4:15d6:9a79:de03]) by BN6PR11MB1393.namprd11.prod.outlook.com ([fe80::a1f4:15d6:9a79:de03%11]) with mapi id 15.20.3153.024; Thu, 2 Jul 2020 02:13:16 +0000 From: "Dandan Bi" To: "devel@edk2.groups.io" , "bret@corthon.com" CC: "Wang, Jian J" , "Wu, Hao A" , "Gao, Liming" Subject: Re: [edk2-devel] [PATCH v6 09/14] MdeModulePkg: Connect VariablePolicy business logic to VariableServices Thread-Topic: [edk2-devel] [PATCH v6 09/14] MdeModulePkg: Connect VariablePolicy business logic to VariableServices Thread-Index: AQHWSVAf7168jDervU6KV0qdu/4mA6jzhewA Date: Thu, 2 Jul 2020 02:13:16 +0000 Message-ID: References: <20200623064104.1908-1-brbarkel@microsoft.com> <20200623064104.1908-10-brbarkel@microsoft.com> In-Reply-To: <20200623064104.1908-10-brbarkel@microsoft.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=intel.com; x-originating-ip: [192.102.204.38] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 798fe50b-377c-4a33-0439-08d81e2d7b4d x-ms-traffictypediagnostic: BN8PR11MB3812: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:10000; x-forefront-prvs: 0452022BE1 x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: Mz0EnuWXwvMoDLBvNppMB+5ZZ8FeQkZftDhiQ3RaSBBfxb9O4jYZzM5EF+6fw2OMMohBjULZbOlqtTrCOu+lQ6YG8yYxNBeL3yBWiLrT71WSg6ty5ZcRaekFIG92PKoFJez5LtXw34rlP6CJUpmoLwVRFcCvEtuyDjZjA1mKwuFkMbfHkI9eMLKD+VeAF1cevr73pxyf9tpA6k64lCmzZpj3PM8DSwd5jYAKF01eLkrQrutq0sNfPJI1S8n4I8IEySycc81TYWxTbVVscf0bD1iuvCPU9hE00sePed3V7Q6DbIxJRQ2qzEtBmp5HzdwWwyyD0BqsAAImsby1iDLv1fBd+nHqkh6nCSRlXkTkCeotQk6P818yAM0a60rXf9r2tf3kkZimcf/AFFUnvxceuTrjikh3QvWgamr/Bc9XdXzNmiEAFqv7u2MMau7guY/rK5puE50hpRJGZLKaqis7hg== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BN6PR11MB1393.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(4636009)(366004)(136003)(39860400002)(396003)(346002)(376002)(76116006)(8936002)(316002)(966005)(55016002)(30864003)(110136005)(33656002)(9686003)(4326008)(107886003)(19627235002)(54906003)(8676002)(83380400001)(2906002)(66946007)(45080400002)(66556008)(64756008)(478600001)(66476007)(86362001)(66446008)(71200400001)(53546011)(6506007)(186003)(5660300002)(7696005)(52536014)(26005)(559001)(579004)(44824005);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: 3Pj4ZyquSZ7r+c3QTSPfTQ7bkgs/5+S7iy8tJ3bhncrc+UJXDU1jJQm57RH3d26zi+NPuAPxbv8Qbu4kOlm2jKamcGYGmWhWQ8oK2VgbpxtUN7otzN5E0FyU4cP2mnO0I1C46z0vnrTLTpeLKRPIVy7NPrp7N3S2k2ONQA8ppYmyKSKq1q5kLbu3la/+RNWTjIdOBTHIfTPe2p+P5aHSW6m9Kln453q8mYoAPop4aiT3hdlDYHRJxWj3Pzr66OBuOj7Scb4pcKDA8sPRhBzG5at2zOMi1LmzlQzF6LWCJyJp4NEJrOlJv6jayjC1Cbq3MzCyFlg5kOaEm73UOVMnWVQZK/mFH6J4VUfwhQCVKFu/INcV8wBFapnhOBvQMeePUkA8IRY/Y+sNoe/EIp6btxAtIpndwdCvZ3vOjuBj+N0ZKTHJtX9kCHk3im3r+U3MMEN/TiD84SO+rrePyUi6qjQKmfqnZKidBMrmwkkhlolHH0z8zOdX01rGQJc1LW8T MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: BN6PR11MB1393.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 798fe50b-377c-4a33-0439-08d81e2d7b4d X-MS-Exchange-CrossTenant-originalarrivaltime: 02 Jul 2020 02:13:16.2532 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: 4l/IftK7BwPkhueCmquLVAfcnA3eSCa0JPmxnJMpfB5Fse3hFJB5+XOjTP+FB+ynoP0LV9O7h8xDwJn7X+EJ8Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN8PR11MB3812 Return-Path: dandan.bi@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable 1 comment inline, please check. Thanks, Dandan > -----Original Message----- > From: devel@edk2.groups.io On Behalf Of Bret > Barkelew > Sent: Tuesday, June 23, 2020 2:41 PM > To: devel@edk2.groups.io > Cc: Wang, Jian J ; Wu, Hao A ; > Gao, Liming > Subject: [edk2-devel] [PATCH v6 09/14] MdeModulePkg: Connect > VariablePolicy business logic to VariableServices >=20 > https://bugzilla.tianocore.org/show_bug.cgi?id=3D2522 >=20 > VariablePolicy is an updated interface to > replace VarLock and VarCheckProtocol. >=20 > Add connective code to publish the VariablePolicy protocol > and wire it to either the SMM communication interface > or directly into the VariablePolicyLib business logic. >=20 > Cc: Jian J Wang > Cc: Hao A Wu > Cc: Liming Gao > Cc: Bret Barkelew > Signed-off-by: Bret Barkelew > --- > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c | = 53 > ++ > MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c > | 642 ++++++++++++++++++++ >=20 > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe. > c | 14 + > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > | 2 + > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf | = 3 > + >=20 > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.i > nf | 10 + > 6 files changed, 724 insertions(+) >=20 > diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c > index 7d2b6c8e1fad..d404d4763e54 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. >=20 > Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
>=20 > (C) Copyright 2015 Hewlett Packard Enterprise Development LP
>=20 > +Copyright (c) Microsoft Corporation. >=20 > SPDX-License-Identifier: BSD-2-Clause-Patent >=20 >=20 >=20 > **/ >=20 >=20 >=20 > #include "Variable.h" >=20 >=20 >=20 > +#include >=20 > +#include >=20 > + >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +ProtocolIsVariablePolicyEnabled ( >=20 > + OUT BOOLEAN *State >=20 > + ); >=20 > + >=20 > EFI_HANDLE mHandle =3D NULL; >=20 > EFI_EVENT mVirtualAddressChangeEvent =3D NULL; >=20 > VOID *mFtwRegistration =3D NULL; >=20 > VOID ***mVarCheckAddressPointer =3D NULL; >=20 > UINTN mVarCheckAddressPointerCount =3D 0; >=20 > EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock =3D > { VariableLockRequestToLock }; >=20 > +EDKII_VARIABLE_POLICY_PROTOCOL mVariablePolicyProtocol =3D > { EDKII_VARIABLE_POLICY_PROTOCOL_REVISION, >=20 > + Disa= bleVariablePolicy, >=20 > + Prot= ocolIsVariablePolicyEnabled, >=20 > + Regi= sterVariablePolicy, >=20 > + Dump= VariablePolicy, >=20 > + Lock= VariablePolicy }; >=20 > EDKII_VAR_CHECK_PROTOCOL mVarCheck =3D > { VarCheckRegisterSetVariableCheckHandler, >=20 > VarC= heckVariablePropertySet, >=20 > VarC= heckVariablePropertyGet }; >=20 > @@ -303,6 +319,8 @@ OnReadyToBoot ( > } >=20 > } >=20 >=20 >=20 > + ASSERT_EFI_ERROR (LockVariablePolicy ()); >=20 > + >=20 > gBS->CloseEvent (Event); >=20 > } >=20 >=20 >=20 > @@ -466,6 +484,28 @@ FtwNotificationEvent ( > } >=20 >=20 >=20 >=20 >=20 > +/** >=20 > + This API function returns whether or not the policy engine is >=20 > + currently being enforced. >=20 > + >=20 > + @param[out] State Pointer to a return value for whether the po= licy > enforcement >=20 > + is currently enabled. >=20 > + >=20 > + @retval EFI_SUCCESS >=20 > + @retval Others An error has prevented this command from > completing. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +ProtocolIsVariablePolicyEnabled ( >=20 > + OUT BOOLEAN *State >=20 > + ) >=20 > +{ >=20 > + *State =3D IsVariablePolicyEnabled (); >=20 > + return EFI_SUCCESS; >=20 > +} 1. [Dandan]: I see other APIs in the VariablePolicyProtocol are using the A= PIs in VariablePolicyLib directly, expect this one. Could we make the IsVariablePolicyEnabled API aligned in protocol and Lib? >=20 > + >=20 > + >=20 > /** >=20 > Variable Driver main entry point. The Variable driver places the 4 EFI >=20 > runtime services in the EFI System Table and installs arch protocols >=20 > @@ -576,6 +616,19 @@ VariableServiceInitialize ( > ); >=20 > ASSERT_EFI_ERROR (Status); >=20 >=20 >=20 > + // Register and initialize the VariablePolicy engine. >=20 > + Status =3D InitVariablePolicyLib (VariableServiceGetVariable); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + Status =3D VarCheckRegisterSetVariableCheckHandler (ValidateSetVariabl= e); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + Status =3D gBS->InstallMultipleProtocolInterfaces ( >=20 > + &mHandle, >=20 > + &gEdkiiVariablePolicyProtocolGuid, >=20 > + &mVariablePolicyProtocol, >=20 > + NULL >=20 > + ); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > return EFI_SUCCESS; >=20 > } >=20 >=20 >=20 > diff --git > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c > new file mode 100644 > index 000000000000..e2d4cf4cec1a > --- /dev/null > +++ > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariablePolicySmmDxe.c > @@ -0,0 +1,642 @@ > +/** @file -- VariablePolicySmmDxe.c >=20 > +This protocol allows communication with Variable Policy Engine. >=20 > + >=20 > +Copyright (c) Microsoft Corporation. >=20 > +SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +#include >=20 > +#include >=20 > + >=20 > +#include >=20 > + >=20 > +#include "Variable.h" >=20 > + >=20 > +EDKII_VARIABLE_POLICY_PROTOCOL mVariablePolicyProtocol; >=20 > +EFI_MM_COMMUNICATION2_PROTOCOL *mMmCommunication; >=20 > + >=20 > +VOID *mMmCommunicationBuffer; >=20 > +UINTN mMmCommunicationBufferSize; >=20 > +EFI_LOCK mMmCommunicationLock; >=20 > + >=20 > +/** >=20 > + Internal helper function to consolidate communication method. >=20 > + >=20 > + @param[in,out] CommBuffer >=20 > + @param[in,out] CommSize Size of the CommBuffer. >=20 > + >=20 > + @retval EFI_STATUS Result from communication method. >=20 > + >=20 > +**/ >=20 > +STATIC >=20 > +EFI_STATUS >=20 > +InternalMmCommunicate ( >=20 > + IN OUT VOID *CommBuffer, >=20 > + IN OUT UINTN *CommSize >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + if (CommBuffer =3D=3D NULL || CommSize =3D=3D NULL) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + Status =3D mMmCommunication->Communicate (mMmCommunication, > CommBuffer, CommBuffer, CommSize); >=20 > + return Status; >=20 > +} >=20 > + >=20 > + >=20 > +/** >=20 > + This API function disables the variable policy enforcement. If it's >=20 > + already been called once, will return EFI_ALREADY_STARTED. >=20 > + >=20 > + @retval EFI_SUCCESS >=20 > + @retval EFI_ALREADY_STARTED Has already been called once this bo= ot. >=20 > + @retval EFI_WRITE_PROTECTED Interface has been locked until rebo= ot. >=20 > + @retval EFI_WRITE_PROTECTED Interface option is disabled by plat= form > PCD. >=20 > + >=20 > +**/ >=20 > +STATIC >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +ProtocolDisableVariablePolicy ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + EFI_MM_COMMUNICATE_HEADER *CommHeader; >=20 > + VAR_CHECK_POLICY_COMM_HEADER *PolicyHeader; >=20 > + UINTN BufferSize; >=20 > + >=20 > + // Check the PCD for convenience. >=20 > + // This would also be rejected by the lib, but why go to MM if we don'= t > have to? >=20 > + if (!PcdGetBool (PcdAllowVariablePolicyEnforcementDisable)) { >=20 > + return EFI_WRITE_PROTECTED; >=20 > + } >=20 > + >=20 > + AcquireLockOnlyAtBootTime (&mMmCommunicationLock); >=20 > + >=20 > + // Set up the MM communication. >=20 > + BufferSize =3D mMmCommunicationBufferSize; >=20 > + CommHeader =3D mMmCommunicationBuffer; >=20 > + PolicyHeader =3D (VAR_CHECK_POLICY_COMM_HEADER*)&CommHeader- > >Data; >=20 > + CopyGuid( &CommHeader->HeaderGuid, > &gVarCheckPolicyLibMmiHandlerGuid ); >=20 > + CommHeader->MessageLength =3D BufferSize; >=20 > + PolicyHeader->Signature =3D VAR_CHECK_POLICY_COMM_SIG; >=20 > + PolicyHeader->Revision =3D VAR_CHECK_POLICY_COMM_REVISION; >=20 > + PolicyHeader->Command =3D VAR_CHECK_POLICY_COMMAND_DISABLE; >=20 > + >=20 > + Status =3D InternalMmCommunicate (CommHeader, &BufferSize); >=20 > + DEBUG(( DEBUG_VERBOSE, "%a - MmCommunication returned %r.\n", > __FUNCTION__, Status )); >=20 > + >=20 > + ReleaseLockOnlyAtBootTime (&mMmCommunicationLock); >=20 > + >=20 > + return (EFI_ERROR( Status )) ? Status : PolicyHeader->Result; >=20 > +} >=20 > + >=20 > + >=20 > +/** >=20 > + This API function returns whether or not the policy engine is >=20 > + currently being enforced. >=20 > + >=20 > + @param[out] State Pointer to a return value for whether the po= licy > enforcement >=20 > + is currently enabled. >=20 > + >=20 > + @retval EFI_SUCCESS >=20 > + @retval Others An error has prevented this command from > completing. >=20 > + >=20 > +**/ >=20 > +STATIC >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +ProtocolIsVariablePolicyEnabled ( >=20 > + OUT BOOLEAN *State >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + EFI_MM_COMMUNICATE_HEADER *CommHeader; >=20 > + VAR_CHECK_POLICY_COMM_HEADER *PolicyHeader; >=20 > + VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS *CommandParams; >=20 > + UINTN BufferSize; >=20 > + >=20 > + if (State =3D=3D NULL) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + AcquireLockOnlyAtBootTime (&mMmCommunicationLock); >=20 > + >=20 > + // Set up the MM communication. >=20 > + BufferSize =3D mMmCommunicationBufferSize; >=20 > + CommHeader =3D mMmCommunicationBuffer; >=20 > + PolicyHeader =3D (VAR_CHECK_POLICY_COMM_HEADER*)&CommHeader- > >Data; >=20 > + CommandParams =3D > (VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS*)(PolicyHeader + 1); >=20 > + CopyGuid( &CommHeader->HeaderGuid, > &gVarCheckPolicyLibMmiHandlerGuid ); >=20 > + CommHeader->MessageLength =3D BufferSize; >=20 > + PolicyHeader->Signature =3D VAR_CHECK_POLICY_COMM_SIG; >=20 > + PolicyHeader->Revision =3D VAR_CHECK_POLICY_COMM_REVISION; >=20 > + PolicyHeader->Command =3D > VAR_CHECK_POLICY_COMMAND_IS_ENABLED; >=20 > + >=20 > + Status =3D InternalMmCommunicate (CommHeader, &BufferSize); >=20 > + DEBUG(( DEBUG_VERBOSE, "%a - MmCommunication returned %r.\n", > __FUNCTION__, Status )); >=20 > + >=20 > + if (!EFI_ERROR( Status )) { >=20 > + Status =3D PolicyHeader->Result; >=20 > + *State =3D CommandParams->State; >=20 > + } >=20 > + >=20 > + ReleaseLockOnlyAtBootTime (&mMmCommunicationLock); >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > + >=20 > +/** >=20 > + This API function validates and registers a new policy with >=20 > + the policy enforcement engine. >=20 > + >=20 > + @param[in] NewPolicy Pointer to the incoming policy structure. >=20 > + >=20 > + @retval EFI_SUCCESS >=20 > + @retval EFI_INVALID_PARAMETER NewPolicy is NULL or is internally > inconsistent. >=20 > + @retval EFI_ALREADY_STARTED An identical matching policy alrea= dy > exists. >=20 > + @retval EFI_WRITE_PROTECTED The interface has been locked unti= l > the next reboot. >=20 > + @retval EFI_UNSUPPORTED Policy enforcement has been disabl= ed. > No reason to add more policies. >=20 > + @retval EFI_ABORTED A calculation error has prevented = this > function from completing. >=20 > + @retval EFI_OUT_OF_RESOURCES Cannot grow the table to hold any > more policies. >=20 > + >=20 > +**/ >=20 > +STATIC >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +ProtocolRegisterVariablePolicy ( >=20 > + IN CONST VARIABLE_POLICY_ENTRY *NewPolicy >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + EFI_MM_COMMUNICATE_HEADER *CommHeader; >=20 > + VAR_CHECK_POLICY_COMM_HEADER *PolicyHeader; >=20 > + VOID *PolicyBuffer; >=20 > + UINTN BufferSize; >=20 > + UINTN RequiredSize; >=20 > + >=20 > + if (NewPolicy =3D=3D NULL) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + // First, make sure that the required size does not exceed the capabil= ities >=20 > + // of the MmCommunication buffer. >=20 > + RequiredSize =3D OFFSET_OF(EFI_MM_COMMUNICATE_HEADER, Data) + > sizeof(VAR_CHECK_POLICY_COMM_HEADER); >=20 > + Status =3D SafeUintnAdd( RequiredSize, NewPolicy->Size, &RequiredSize = ); >=20 > + if (EFI_ERROR( Status ) || RequiredSize > mMmCommunicationBufferSize) > { >=20 > + DEBUG(( DEBUG_ERROR, "%a - Policy too large for buffer! %r, %d > %d > \n", __FUNCTION__, >=20 > + Status, RequiredSize, mMmCommunicationBufferSize )); >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + >=20 > + AcquireLockOnlyAtBootTime (&mMmCommunicationLock); >=20 > + >=20 > + // Set up the MM communication. >=20 > + BufferSize =3D mMmCommunicationBufferSize; >=20 > + CommHeader =3D mMmCommunicationBuffer; >=20 > + PolicyHeader =3D (VAR_CHECK_POLICY_COMM_HEADER*)&CommHeader- > >Data; >=20 > + PolicyBuffer =3D (VOID*)(PolicyHeader + 1); >=20 > + CopyGuid( &CommHeader->HeaderGuid, > &gVarCheckPolicyLibMmiHandlerGuid ); >=20 > + CommHeader->MessageLength =3D BufferSize; >=20 > + PolicyHeader->Signature =3D VAR_CHECK_POLICY_COMM_SIG; >=20 > + PolicyHeader->Revision =3D VAR_CHECK_POLICY_COMM_REVISION; >=20 > + PolicyHeader->Command =3D VAR_CHECK_POLICY_COMMAND_REGISTER; >=20 > + >=20 > + // Copy the policy into place. This copy is safe because we've already > tested above. >=20 > + CopyMem( PolicyBuffer, NewPolicy, NewPolicy->Size ); >=20 > + >=20 > + Status =3D InternalMmCommunicate (CommHeader, &BufferSize); >=20 > + DEBUG(( DEBUG_VERBOSE, "%a - MmCommunication returned %r.\n", > __FUNCTION__, Status )); >=20 > + >=20 > + ReleaseLockOnlyAtBootTime (&mMmCommunicationLock); >=20 > + >=20 > + return (EFI_ERROR( Status )) ? Status : PolicyHeader->Result; >=20 > +} >=20 > + >=20 > + >=20 > +/** >=20 > + This helper function takes care of the overhead of formatting, sending= , > and interpreting >=20 > + the results for a single DumpVariablePolicy request. >=20 > + >=20 > + @param[in] PageRequested The page of the paginated results from > MM. 0 for metadata. >=20 > + @param[out] TotalSize The total size of the entire buffer. R= eturned as > part of metadata. >=20 > + @param[out] PageSize The size of the current page being ret= urned. > Not valid as part of metadata. >=20 > + @param[out] HasMore A flag indicating whether there are mo= re > pages after this one. >=20 > + @param[out] Buffer The start of the current page from MM. >=20 > + >=20 > + @retval EFI_SUCCESS Output params have been updated (e= ither > metadata or dump page). >=20 > + @retval EFI_INVALID_PARAMETER One of the output params is NULL. >=20 > + @retval Others Response from MM handler. >=20 > + >=20 > +**/ >=20 > +STATIC >=20 > +EFI_STATUS >=20 > +DumpVariablePolicyHelper ( >=20 > + IN UINT32 PageRequested, >=20 > + OUT UINT32 *TotalSize, >=20 > + OUT UINT32 *PageSize, >=20 > + OUT BOOLEAN *HasMore, >=20 > + OUT UINT8 **Buffer >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + EFI_MM_COMMUNICATE_HEADER *CommHeader; >=20 > + VAR_CHECK_POLICY_COMM_HEADER *PolicyHeader; >=20 > + VAR_CHECK_POLICY_COMM_DUMP_PARAMS *CommandParams; >=20 > + UINTN BufferSize; >=20 > + >=20 > + if (TotalSize =3D=3D NULL || PageSize =3D=3D NULL || HasMore =3D=3D NU= LL || Buffer > =3D=3D NULL) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + // Set up the MM communication. >=20 > + BufferSize =3D mMmCommunicationBufferSize; >=20 > + CommHeader =3D mMmCommunicationBuffer; >=20 > + PolicyHeader =3D (VAR_CHECK_POLICY_COMM_HEADER*)&CommHeader- > >Data; >=20 > + CommandParams =3D > (VAR_CHECK_POLICY_COMM_DUMP_PARAMS*)(PolicyHeader + 1); >=20 > + CopyGuid( &CommHeader->HeaderGuid, > &gVarCheckPolicyLibMmiHandlerGuid ); >=20 > + CommHeader->MessageLength =3D BufferSize; >=20 > + PolicyHeader->Signature =3D VAR_CHECK_POLICY_COMM_SIG; >=20 > + PolicyHeader->Revision =3D VAR_CHECK_POLICY_COMM_REVISION; >=20 > + PolicyHeader->Command =3D VAR_CHECK_POLICY_COMMAND_DUMP; >=20 > + >=20 > + CommandParams->PageRequested =3D PageRequested; >=20 > + >=20 > + Status =3D InternalMmCommunicate (CommHeader, &BufferSize); >=20 > + DEBUG(( DEBUG_VERBOSE, "%a - MmCommunication returned %r.\n", > __FUNCTION__, Status )); >=20 > + >=20 > + if (!EFI_ERROR( Status )) { >=20 > + Status =3D PolicyHeader->Result; >=20 > + *TotalSize =3D CommandParams->TotalSize; >=20 > + *PageSize =3D CommandParams->PageSize; >=20 > + *HasMore =3D CommandParams->HasMore; >=20 > + *Buffer =3D (UINT8*)(CommandParams + 1); >=20 > + } >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > + >=20 > +/** >=20 > + This API function will dump the entire contents of the variable policy= table. >=20 > + >=20 > + Similar to GetVariable, the first call can be made with a 0 size and i= t will > return >=20 > + the size of the buffer required to hold the entire table. >=20 > + >=20 > + @param[out] Policy Pointer to the policy buffer. Can be NULL if S= ize is 0. >=20 > + @param[in,out] Size On input, the size of the output buffer. On ou= tput, > the size >=20 > + of the data returned. >=20 > + >=20 > + @retval EFI_SUCCESS Policy data is in the output buffe= r and Size > has been updated. >=20 > + @retval EFI_INVALID_PARAMETER Size is NULL, or Size is non-zero = and > Policy is NULL. >=20 > + @retval EFI_BUFFER_TOO_SMALL Size is insufficient to hold polic= y. Size > updated with required size. >=20 > + >=20 > +**/ >=20 > +STATIC >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +ProtocolDumpVariablePolicy ( >=20 > + OUT UINT8 *Policy OPTIONAL, >=20 > + IN OUT UINT32 *Size >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINT8 *Source; >=20 > + UINT8 *Destination; >=20 > + UINT32 PolicySize; >=20 > + UINT32 PageSize; >=20 > + BOOLEAN HasMore; >=20 > + UINT32 PageIndex; >=20 > + >=20 > + if (Size =3D=3D NULL || (*Size > 0 && Policy =3D=3D NULL)) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + AcquireLockOnlyAtBootTime (&mMmCommunicationLock); >=20 > + >=20 > + // Repeat this whole process until we either have a failure case or ge= t the > entire buffer. >=20 > + do { >=20 > + // First, we must check the zero page to determine the buffer size a= nd >=20 > + // reset the internal state. >=20 > + PolicySize =3D 0; >=20 > + PageSize =3D 0; >=20 > + HasMore =3D FALSE; >=20 > + Status =3D DumpVariablePolicyHelper (0, &PolicySize, &PageSize, &Has= More, > &Source); >=20 > + if (EFI_ERROR (Status)) { >=20 > + break; >=20 > + } >=20 > + >=20 > + // If we're good, we can at least check the required size now. >=20 > + if (*Size < PolicySize) { >=20 > + *Size =3D PolicySize; >=20 > + Status =3D EFI_BUFFER_TOO_SMALL; >=20 > + break; >=20 > + } >=20 > + >=20 > + // On further thought, let's update the size either way. >=20 > + *Size =3D PolicySize; >=20 > + // And get ready to ROCK. >=20 > + Destination =3D Policy; >=20 > + >=20 > + // Keep looping and copying until we're either done or freak out. >=20 > + for (PageIndex =3D 1; !EFI_ERROR (Status) && HasMore && PageIndex < > MAX_UINT32; PageIndex++) { >=20 > + Status =3D DumpVariablePolicyHelper (PageIndex, &PolicySize, &Page= Size, > &HasMore, &Source); >=20 > + if (!EFI_ERROR (Status)) { >=20 > + CopyMem (Destination, Source, PageSize); >=20 > + Destination +=3D PageSize; >=20 > + } >=20 > + } >=20 > + >=20 > + // Next, we check to see whether >=20 > + } while (Status =3D=3D EFI_TIMEOUT); >=20 > + >=20 > + ReleaseLockOnlyAtBootTime (&mMmCommunicationLock); >=20 > + >=20 > + // There's currently no use for this, but it shouldn't be hard to impl= ement. >=20 > + return Status; >=20 > +} >=20 > + >=20 > + >=20 > +/** >=20 > + This API function locks the interface so that no more policy updates >=20 > + can be performed or changes made to the enforcement until the next > boot. >=20 > + >=20 > + @retval EFI_SUCCESS >=20 > + @retval Others An error has prevented this command from > completing. >=20 > + >=20 > +**/ >=20 > +STATIC >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +ProtocolLockVariablePolicy ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + EFI_MM_COMMUNICATE_HEADER *CommHeader; >=20 > + VAR_CHECK_POLICY_COMM_HEADER *PolicyHeader; >=20 > + UINTN BufferSize; >=20 > + >=20 > + AcquireLockOnlyAtBootTime (&mMmCommunicationLock); >=20 > + >=20 > + // Set up the MM communication. >=20 > + BufferSize =3D mMmCommunicationBufferSize; >=20 > + CommHeader =3D mMmCommunicationBuffer; >=20 > + PolicyHeader =3D (VAR_CHECK_POLICY_COMM_HEADER*)&CommHeader- > >Data; >=20 > + CopyGuid( &CommHeader->HeaderGuid, > &gVarCheckPolicyLibMmiHandlerGuid ); >=20 > + CommHeader->MessageLength =3D BufferSize; >=20 > + PolicyHeader->Signature =3D VAR_CHECK_POLICY_COMM_SIG; >=20 > + PolicyHeader->Revision =3D VAR_CHECK_POLICY_COMM_REVISION; >=20 > + PolicyHeader->Command =3D VAR_CHECK_POLICY_COMMAND_LOCK; >=20 > + >=20 > + Status =3D InternalMmCommunicate (CommHeader, &BufferSize); >=20 > + DEBUG(( DEBUG_VERBOSE, "%a - MmCommunication returned %r.\n", > __FUNCTION__, Status )); >=20 > + >=20 > + ReleaseLockOnlyAtBootTime (&mMmCommunicationLock); >=20 > + >=20 > + return (EFI_ERROR( Status )) ? Status : PolicyHeader->Result; >=20 > +} >=20 > + >=20 > + >=20 > +/** >=20 > + This helper function locates the shared comm buffer and assigns it to = input > pointers. >=20 > + >=20 > + @param[in,out] BufferSize On input, the minimum buffer size requ= ired > INCLUDING the MM communicate header. >=20 > + On output, the size of the matching bu= ffer found. >=20 > + @param[out] LocatedBuffer A pointer to the matching buffer. >=20 > + >=20 > + @retval EFI_SUCCESS >=20 > + @retval EFI_INVALID_PARAMETER One of the output pointers was > NULL. >=20 > + @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate a > comm buffer. >=20 > + >=20 > +**/ >=20 > +STATIC >=20 > +EFI_STATUS >=20 > +InitMmCommonCommBuffer ( >=20 > + IN OUT UINTN *BufferSize, >=20 > + OUT VOID **LocatedBuffer >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + >=20 > + Status =3D EFI_SUCCESS; >=20 > + >=20 > + // Make sure that we're working with good pointers. >=20 > + if (BufferSize =3D=3D NULL || LocatedBuffer =3D=3D NULL) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + // Allocate the runtime memory for the comm buffer. >=20 > + *LocatedBuffer =3D AllocateRuntimePool (*BufferSize); >=20 > + if (*LocatedBuffer =3D=3D NULL) { >=20 > + Status =3D EFI_OUT_OF_RESOURCES; >=20 > + *BufferSize =3D 0; >=20 > + } >=20 > + >=20 > + EfiInitializeLock (&mMmCommunicationLock, TPL_NOTIFY); >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > + >=20 > +/** >=20 > + This helper is responsible for telemetry and any other actions that >=20 > + need to be taken if the VariablePolicy fails to lock. >=20 > + >=20 > + NOTE: It's possible that parts of this handling will need to become >=20 > + part of a platform policy. >=20 > + >=20 > + @param[in] FailureStatus The failure that was reported by > LockVariablePolicy >=20 > + >=20 > +**/ >=20 > +STATIC >=20 > +VOID >=20 > +VariablePolicyHandleFailureToLock ( >=20 > + IN EFI_STATUS FailureStatus >=20 > + ) >=20 > +{ >=20 > + // For now, there's no agreed-upon policy for this. >=20 > + return; >=20 > +} >=20 > + >=20 > + >=20 > +/** >=20 > + ReadyToBoot Callback >=20 > + Lock the VariablePolicy interface if it hasn't already been locked. >=20 > + >=20 > + @param[in] Event Event whose notification function is being invok= ed >=20 > + @param[in] Context Pointer to the notification function's context >=20 > + >=20 > +**/ >=20 > +STATIC >=20 > +VOID >=20 > +EFIAPI >=20 > +LockPolicyInterfaceAtReadyToBoot ( >=20 > + IN EFI_EVENT Event, >=20 > + IN VOID *Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + >=20 > + Status =3D ProtocolLockVariablePolicy(); >=20 > + >=20 > + if (EFI_ERROR( Status )) { >=20 > + VariablePolicyHandleFailureToLock( Status ); >=20 > + } >=20 > + else { >=20 > + gBS->CloseEvent( Event ); >=20 > + } >=20 > + >=20 > +} >=20 > + >=20 > + >=20 > +/** >=20 > + Convert internal pointer addresses to virtual addresses. >=20 > + >=20 > + @param[in] Event Event whose notification function is being invok= ed. >=20 > + @param[in] Context The pointer to the notification function's conte= xt, > which >=20 > + is implementation-dependent. >=20 > +**/ >=20 > +STATIC >=20 > +VOID >=20 > +EFIAPI >=20 > +VariablePolicyVirtualAddressCallback ( >=20 > + IN EFI_EVENT Event, >=20 > + IN VOID *Context >=20 > + ) >=20 > +{ >=20 > + EfiConvertPointer (0, (VOID **)&mMmCommunication); >=20 > + EfiConvertPointer (0, (VOID **)&mMmCommunicationBuffer); >=20 > +} >=20 > + >=20 > + >=20 > +/** >=20 > + The driver's entry point. >=20 > + >=20 > + @param[in] ImageHandle The firmware allocated handle for the EFI imag= e. >=20 > + @param[in] SystemTable A pointer to the EFI System Table. >=20 > + >=20 > + @retval EFI_SUCCESS The entry point executed successfully. >=20 > + @retval other Some error occured when executing this entry p= oint. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VariablePolicySmmDxeMain ( >=20 > + IN EFI_HANDLE ImageHandle, >=20 > + IN EFI_SYSTEM_TABLE *SystemTable >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + BOOLEAN ProtocolInstalled; >=20 > + BOOLEAN CallbackRegistered; >=20 > + BOOLEAN VirtualAddressChangeRegistered; >=20 > + EFI_EVENT ReadyToBootEvent; >=20 > + EFI_EVENT VirtualAddressChangeEvent; >=20 > + >=20 > + Status =3D EFI_SUCCESS; >=20 > + ProtocolInstalled =3D FALSE; >=20 > + CallbackRegistered =3D FALSE; >=20 > + VirtualAddressChangeRegistered =3D FALSE; >=20 > + >=20 > + // Update the minimum buffer size. >=20 > + mMmCommunicationBufferSize =3D > VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE; >=20 > + // Locate the shared comm buffer to use for sending MM commands. >=20 > + Status =3D InitMmCommonCommBuffer( &mMmCommunicationBufferSize, > &mMmCommunicationBuffer ); >=20 > + if (EFI_ERROR( Status )) { >=20 > + DEBUG((DEBUG_ERROR, "%a - Failed to locate a viable MM comm > buffer! %r\n", __FUNCTION__, Status)); >=20 > + ASSERT_EFI_ERROR( Status ); >=20 > + return Status; >=20 > + } >=20 > + >=20 > + // Locate the MmCommunication protocol. >=20 > + Status =3D gBS->LocateProtocol( &gEfiMmCommunication2ProtocolGuid, > NULL, (VOID**)&mMmCommunication ); >=20 > + if (EFI_ERROR( Status )) { >=20 > + DEBUG((DEBUG_ERROR, "%a - Failed to locate MmCommunication > protocol! %r\n", __FUNCTION__, Status)); >=20 > + ASSERT_EFI_ERROR( Status ); >=20 > + return Status; >=20 > + } >=20 > + >=20 > + // Configure the VariablePolicy protocol structure. >=20 > + mVariablePolicyProtocol.Revision =3D > EDKII_VARIABLE_POLICY_PROTOCOL_REVISION; >=20 > + mVariablePolicyProtocol.DisableVariablePolicy =3D > ProtocolDisableVariablePolicy; >=20 > + mVariablePolicyProtocol.IsVariablePolicyEnabled =3D > ProtocolIsVariablePolicyEnabled; >=20 > + mVariablePolicyProtocol.RegisterVariablePolicy =3D > ProtocolRegisterVariablePolicy; >=20 > + mVariablePolicyProtocol.DumpVariablePolicy =3D > ProtocolDumpVariablePolicy; >=20 > + mVariablePolicyProtocol.LockVariablePolicy =3D ProtocolLockVariab= lePolicy; >=20 > + >=20 > + // Register all the protocols and return the status. >=20 > + Status =3D gBS->InstallMultipleProtocolInterfaces( &ImageHandle, >=20 > + &gEdkiiVariablePolicy= ProtocolGuid, > &mVariablePolicyProtocol, >=20 > + NULL ); >=20 > + if (EFI_ERROR( Status )) { >=20 > + DEBUG(( DEBUG_ERROR, "%a - Failed to install protocol! %r\n", > __FUNCTION__, Status )); >=20 > + goto Exit; >=20 > + } >=20 > + else { >=20 > + ProtocolInstalled =3D TRUE; >=20 > + } >=20 > + >=20 > + // >=20 > + // Register a callback for ReadyToBoot so that the interface is at lea= st > locked before >=20 > + // dispatching any bootloaders or UEFI apps. >=20 > + Status =3D gBS->CreateEventEx( EVT_NOTIFY_SIGNAL, >=20 > + TPL_CALLBACK, >=20 > + LockPolicyInterfaceAtReadyToBoot, >=20 > + NULL, >=20 > + &gEfiEventReadyToBootGuid, >=20 > + &ReadyToBootEvent ); >=20 > + if (EFI_ERROR( Status )) { >=20 > + DEBUG(( DEBUG_ERROR, "%a - Failed to create ReadyToBoot > event! %r\n", __FUNCTION__, Status )); >=20 > + goto Exit; >=20 > + } >=20 > + else { >=20 > + CallbackRegistered =3D TRUE; >=20 > + } >=20 > + >=20 > + // >=20 > + // Register a VirtualAddressChange callback for the MmComm protocol > and Comm buffer. >=20 > + Status =3D gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, >=20 > + TPL_NOTIFY, >=20 > + VariablePolicyVirtualAddressCallback, >=20 > + NULL, >=20 > + &gEfiEventVirtualAddressChangeGuid, >=20 > + &VirtualAddressChangeEvent); >=20 > + if (EFI_ERROR( Status )) { >=20 > + DEBUG(( DEBUG_ERROR, "%a - Failed to create VirtualAddressChange > event! %r\n", __FUNCTION__, Status )); >=20 > + goto Exit; >=20 > + } >=20 > + else { >=20 > + VirtualAddressChangeRegistered =3D TRUE; >=20 > + } >=20 > + >=20 > + >=20 > +Exit: >=20 > + // >=20 > + // If we're about to return a failed status (and unload this driver), = we must > first undo anything that >=20 > + // has been successfully done. >=20 > + if (EFI_ERROR( Status )) { >=20 > + if (ProtocolInstalled) { >=20 > + gBS->UninstallProtocolInterface( &ImageHandle, > &gEdkiiVariablePolicyProtocolGuid, &mVariablePolicyProtocol ); >=20 > + } >=20 > + if (CallbackRegistered) { >=20 > + gBS->CloseEvent( ReadyToBootEvent ); >=20 > + } >=20 > + if (VirtualAddressChangeRegistered) { >=20 > + gBS->CloseEvent( VirtualAddressChangeEvent ); >=20 > + } >=20 > + } >=20 > + >=20 > + return Status; >=20 > +} >=20 > diff --git > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.c > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.c > index 663a1aaa128f..c47e614d81f4 100644 > --- > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.c > +++ > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.c > @@ -65,6 +65,17 @@ EFI_LOCK mVariableServicesLock= ; > EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock; >=20 > EDKII_VAR_CHECK_PROTOCOL mVarCheck; >=20 >=20 >=20 > +/** >=20 > + The logic to initialize the VariablePolicy engine is in its own file. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +VariablePolicySmmDxeMain ( >=20 > + IN EFI_HANDLE ImageHandle, >=20 > + IN EFI_SYSTEM_TABLE *SystemTable >=20 > + ); >=20 > + >=20 > /** >=20 > Some Secure Boot Policy Variable may update following other variable > changes(SecureBoot follows PK change, etc). >=20 > Record their initial State when variable write service is ready. >=20 > @@ -1796,6 +1807,9 @@ VariableSmmRuntimeInitialize ( > &mVirtualAddressChangeEvent >=20 > ); >=20 >=20 >=20 > + // Initialize the VariablePolicy protocol and engine. >=20 > + VariablePolicySmmDxeMain (ImageHandle, SystemTable); >=20 > + >=20 > return EFI_SUCCESS; >=20 > } >=20 >=20 >=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. >=20 > # >=20 > # Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
>=20 > +# Copyright (c) Microsoft Corporation. >=20 > # SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > # >=20 > ## >=20 > @@ -69,6 +70,7 @@ [LibraryClasses] > TpmMeasurementLib >=20 > AuthVariableLib >=20 > VarCheckLib >=20 > + VariablePolicyLib >=20 >=20 >=20 > [Protocols] >=20 > gEfiFirmwareVolumeBlockProtocolGuid ## CONSUMES >=20 > diff --git > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > b/MdeModulePkg/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, an= d the > behavior is undefined. >=20 > # >=20 > # Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
>=20 > +# Copyright (c) Microsoft Corporation. >=20 > # SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > # >=20 > ## >=20 > @@ -78,6 +79,8 @@ [LibraryClasses] > AuthVariableLib >=20 > VarCheckLib >=20 > UefiBootServicesTableLib >=20 > + VariablePolicyLib >=20 > + VariablePolicyHelperLib >=20 >=20 >=20 > [Protocols] >=20 > gEfiSmmFirmwareVolumeBlockProtocolGuid ## CONSUMES >=20 > diff --git > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.inf > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.inf > index 01564e4c5068..f217530b2985 100644 > --- > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.inf > +++ > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.inf > @@ -14,6 +14,7 @@ > # the authentication service provided in this driver will be broken, an= d the > behavior is undefined. >=20 > # >=20 > # Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
>=20 > +# Copyright (c) Microsoft Corporation.
>=20 > # SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > # >=20 > ## >=20 > @@ -42,6 +43,7 @@ [Sources] > VariableParsing.c >=20 > VariableParsing.h >=20 > Variable.h >=20 > + VariablePolicySmmDxe.c >=20 >=20 >=20 > [Packages] >=20 > MdePkg/MdePkg.dec >=20 > @@ -56,6 +58,8 @@ [LibraryClasses] > DxeServicesTableLib >=20 > UefiDriverEntryPoint >=20 > TpmMeasurementLib >=20 > + SafeIntLib >=20 > + PcdLib >=20 >=20 >=20 > [Protocols] >=20 > gEfiVariableWriteArchProtocolGuid ## PRODUCES >=20 > @@ -67,11 +71,15 @@ [Protocols] > gEfiSmmVariableProtocolGuid >=20 > gEdkiiVariableLockProtocolGuid ## PRODUCES >=20 > gEdkiiVarCheckProtocolGuid ## PRODUCES >=20 > + gEdkiiVariablePolicyProtocolGuid ## PRODUCES >=20 >=20 >=20 > [FeaturePcd] >=20 > gEfiMdeModulePkgTokenSpaceGuid.PcdEnableVariableRuntimeCache > ## CONSUMES >=20 > gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics = ## > CONSUMES >=20 >=20 >=20 > +[Pcd] >=20 > + > gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDis > able ## CONSUMES >=20 > + >=20 > [Guids] >=20 > ## PRODUCES ## GUID # Signature of Variable store header >=20 > ## CONSUMES ## GUID # Signature of Variable store header >=20 > @@ -99,6 +107,8 @@ [Guids] > ## SOMETIMES_CONSUMES ## Variable:L"dbt" >=20 > gEfiImageSecurityDatabaseGuid >=20 >=20 >=20 > + gVarCheckPolicyLibMmiHandlerGuid >=20 > + >=20 > [Depex] >=20 > gEfiMmCommunication2ProtocolGuid >=20 >=20 >=20 > -- > 2.26.2.windows.1.8.g01c50adf56.20200515075929 >=20 >=20 > -=3D-=3D-=3D-=3D-=3D-=3D > Groups.io Links: You receive all messages sent to this group. >=20 > View/Reply Online (#61585): https://edk2.groups.io/g/devel/message/61585 > Mute This Topic: https://groups.io/mt/75057694/1768738 > Group Owner: devel+owner@edk2.groups.io > Unsubscribe: https://edk2.groups.io/g/devel/unsub [dandan.bi@intel.com] > -=3D-=3D-=3D-=3D-=3D-=3D