From mboxrd@z Thu Jan 1 00:00:00 1970 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 Authentication-Results: mx.groups.io; dkim=pass header.i=@corthon-com.20150623.gappssmtp.com header.s=20150623 header.b=PJDBl/KS; spf=none, err=permanent DNS error (domain: corthon.com, ip: 209.85.214.196, mailfrom: bret@corthon.com) Received: by mail-pl1-f196.google.com with SMTP id j5so4254010plk.7 for ; Sun, 08 Nov 2020 22:46:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=corthon-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=EiYa7ntFw7KgQxoC1WrEYgKJcYR7b2d3e5VOmEfnWIs=; b=PJDBl/KSaQtsnwR6oV1QGaC71CSoFIJnFmPjMR7Wd6kIP6Pk9ANL/2AnTrqPzq8bmZ 8ROx7MQe3u4xKrbYQEKxlWPi7zym21rmuKkcppDN50Ss+PIuw5k3TMZmPflsqS+hGeho jxUelkfrtq/9XH/ohc4K7vR+/+cnp5L6qroxIE5mtgWobsTkJHlxywb2Q/TQiII6RF9p wNXeuhUlBW5B+P1AVHfu/07EpwEVrQWm7Gu6ZdqocUbK9PYUZNoaM09svBJcd07abDzz kOtkElixXTA1Y+bM5yDU3XEfXbSEFgpJIdeAtAl0rQ5S0U73c0a81bTGik2WcVbWfVfm Xj5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=EiYa7ntFw7KgQxoC1WrEYgKJcYR7b2d3e5VOmEfnWIs=; b=P3NEzpOTN1pDGZZ1wO09nvZyU+CTyAVzoIt0vdHLh6aSKk1dl25f93gfuCxb7rBgkt j3eifvZnvniucM1uBtAMyJt12gEC/gXJ+j6TBLTzJ1gYHFJjOo5QAhUJrzVMq2gdYUeM xgujfGyKVLHazDyZ10BRpXvP3ebmI41v/871zGQSI7A0Y+Qa7mud6ay/WPVw/CBJdANM Ms3FkoZTPXRihSpuHRYn7AuRHlRT9/d+ERztYX7g2OufbEd9sJYa/AdxuKvQFlnW5ux9 U6JdqjhRAoXg0kkr5auIUO1XXixJ4LeLHcx1ID9lC4i44qEmnvpiG1RP35D9dZd9Q+4O Go/Q== X-Gm-Message-State: AOAM530UHuhYAAsx8ZXe7TsWB68ReEkD7OqKmsE+PY36f5e184xOQYpE ie1wlCekRqB5giscfghjj3F3y0B1UOfnq3eU 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) Return-Path: 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: [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> X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20201109064522.919-1-bret.barkelew@microsoft.com> References: <20201109064522.919-1-bret.barkelew@microsoft.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=0D +This is a NULL library instance that leverages the VarCheck interface=0D +and the business logic behind the VariablePolicy code to make its decision= s.=0D +=0D +Copyright (c) Microsoft Corporation.=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +#include =0D +=0D +#include =0D +#include =0D +=0D +#include =0D +=0D +//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0D +// As a VarCheck library, we're linked into the VariableServices=0D +// and may not be able to call them indirectly. To get around this,=0D +// use the internal GetVariable function to query the variable store.=0D +//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0D +EFI_STATUS=0D +EFIAPI=0D +VariableServiceGetVariable (=0D + IN CHAR16 *VariableName,=0D + IN EFI_GUID *VendorGuid,=0D + OUT UINT32 *Attributes OPTIONAL,=0D + IN OUT UINTN *DataSize,=0D + OUT VOID *Data=0D + );=0D +=0D +=0D +UINT8 mSecurityEvalBuffer[VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE];=0D +=0D +// Pagination Cache Variables=0D +UINT8 *mPaginationCache =3D NULL;=0D +UINTN mPaginationCacheSize =3D 0;=0D +UINT32 mCurrentPaginationCommand =3D 0;=0D +=0D +=0D +/**=0D + MM Communication Handler to recieve commands from the DXE protocol for=0D + Variable Policies. This communication channel is used to register new po= licies=0D + and poll and toggle the enforcement of variable policies.=0D +=0D + @param[in] DispatchHandle All parameters standard to MM commun= ications convention.=0D + @param[in] RegisterContext All parameters standard to MM commun= ications convention.=0D + @param[in,out] CommBuffer All parameters standard to MM commun= ications convention.=0D + @param[in,out] CommBufferSize All parameters standard to MM commun= ications convention.=0D +=0D + @retval EFI_SUCCESS=0D + @retval EFI_INVALID_PARAMETER CommBuffer or CommBufferSize is null= pointer.=0D + @retval EFI_INVALID_PARAMETER CommBuffer size is wrong.=0D + @retval EFI_INVALID_PARAMETER Revision or signature don't match.=0D +=0D +**/=0D +STATIC=0D +EFI_STATUS=0D +EFIAPI=0D +VarCheckPolicyLibMmiHandler (=0D + IN EFI_HANDLE DispatchHandle,=0D + IN CONST VOID *RegisterContext,=0D + IN OUT VOID *CommBuffer,=0D + IN OUT UINTN *CommBufferSize=0D + )=0D +{=0D + UINTN InternalCommBufferSize;=0D + VOID *InternalCommBuffer;=0D + EFI_STATUS Status;=0D + EFI_STATUS SubCommandStatus;=0D + VAR_CHECK_POLICY_COMM_HEADER *PolicyCommmHeader;=0D + VAR_CHECK_POLICY_COMM_HEADER *InternalPolicyCommmHeader;=0D + VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS *IsEnabledParams;=0D + VAR_CHECK_POLICY_COMM_DUMP_PARAMS *DumpParamsIn;=0D + VAR_CHECK_POLICY_COMM_DUMP_PARAMS *DumpParamsOut;=0D + UINT8 *DumpInputBuffer;=0D + UINT8 *DumpOutputBuffer;=0D + UINTN DumpTotalPages;=0D + VARIABLE_POLICY_ENTRY *PolicyEntry;=0D + UINTN ExpectedSize;=0D + UINT32 TempSize;=0D +=0D + Status =3D EFI_SUCCESS;=0D +=0D + //=0D + // Validate some input parameters.=0D + //=0D + // If either of the pointers are NULL, we can't proceed.=0D + if (CommBuffer =3D=3D NULL || CommBufferSize =3D=3D NULL) {=0D + DEBUG(( DEBUG_INFO, "%a - Invalid comm buffer pointers!\n", __FUNCTION= __ ));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D + // Make sure that the buffer does not overlap SMM.=0D + // This should be covered by the SmiManage infrastructure, but just to b= e safe...=0D + InternalCommBufferSize =3D *CommBufferSize;=0D + if (InternalCommBufferSize > VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE || !Sm= mIsBufferOutsideSmmValid((UINTN)CommBuffer, (UINT64)InternalCommBufferSize)= ) {=0D + DEBUG ((DEBUG_ERROR, "%a - Invalid CommBuffer supplied! 0x%016lX[0x%01= 6lX]\n", __FUNCTION__, CommBuffer, InternalCommBufferSize));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D + // If the size does not meet a minimum threshold, we cannot proceed.=0D + ExpectedSize =3D sizeof(VAR_CHECK_POLICY_COMM_HEADER);=0D + if (InternalCommBufferSize < ExpectedSize) {=0D + DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNCTION= __, InternalCommBufferSize, ExpectedSize ));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Before proceeding any further, copy the buffer internally so that we = can compare=0D + // without worrying about TOCTOU.=0D + //=0D + InternalCommBuffer =3D &mSecurityEvalBuffer[0];=0D + CopyMem(InternalCommBuffer, CommBuffer, InternalCommBufferSize);=0D + PolicyCommmHeader =3D CommBuffer;=0D + InternalPolicyCommmHeader =3D InternalCommBuffer;=0D + // Check the revision and the signature of the comm header.=0D + if (InternalPolicyCommmHeader->Signature !=3D VAR_CHECK_POLICY_COMM_SIG = ||=0D + InternalPolicyCommmHeader->Revision !=3D VAR_CHECK_POLICY_COMM_REVIS= ION) {=0D + DEBUG(( DEBUG_INFO, "%a - Signature or revision are incorrect!\n", __F= UNCTION__ ));=0D + // We have verified the buffer is not null and have enough size to hol= d Result field.=0D + PolicyCommmHeader->Result =3D EFI_INVALID_PARAMETER;=0D + return EFI_SUCCESS;=0D + }=0D +=0D + // If we're in the middle of a paginated dump and any other command is s= ent,=0D + // pagination cache must be cleared.=0D + if (mPaginationCache !=3D NULL && InternalPolicyCommmHeader->Command != =3D mCurrentPaginationCommand) {=0D + FreePool (mPaginationCache);=0D + mPaginationCache =3D NULL;=0D + mPaginationCacheSize =3D 0;=0D + mCurrentPaginationCommand =3D 0;=0D + }=0D +=0D + //=0D + // Now we can process the command as it was sent.=0D + //=0D + PolicyCommmHeader->Result =3D EFI_ABORTED; // Set a default return fo= r incomplete commands.=0D + switch(InternalPolicyCommmHeader->Command) {=0D + case VAR_CHECK_POLICY_COMMAND_DISABLE:=0D + PolicyCommmHeader->Result =3D DisableVariablePolicy();=0D + break;=0D +=0D + case VAR_CHECK_POLICY_COMMAND_IS_ENABLED:=0D + // Make sure that we're dealing with a reasonable size.=0D + // This add should be safe because these are fixed sizes so far.=0D + ExpectedSize +=3D sizeof(VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS);=0D + if (InternalCommBufferSize < ExpectedSize) {=0D + DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNC= TION__, InternalCommBufferSize, ExpectedSize ));=0D + PolicyCommmHeader->Result =3D EFI_INVALID_PARAMETER;=0D + break;=0D + }=0D +=0D + // Now that we know we've got a valid size, we can fill in the rest = of the data.=0D + IsEnabledParams =3D (VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS*)((UINT= 8*)CommBuffer + sizeof(VAR_CHECK_POLICY_COMM_HEADER));=0D + IsEnabledParams->State =3D IsVariablePolicyEnabled();=0D + PolicyCommmHeader->Result =3D EFI_SUCCESS;=0D + break;=0D +=0D + case VAR_CHECK_POLICY_COMMAND_REGISTER:=0D + // Make sure that we're dealing with a reasonable size.=0D + // This add should be safe because these are fixed sizes so far.=0D + ExpectedSize +=3D sizeof(VARIABLE_POLICY_ENTRY);=0D + if (InternalCommBufferSize < ExpectedSize) {=0D + DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNC= TION__, InternalCommBufferSize, ExpectedSize ));=0D + PolicyCommmHeader->Result =3D EFI_INVALID_PARAMETER;=0D + break;=0D + }=0D +=0D + // At the very least, we can assume that we're working with a valid = policy entry.=0D + // Time to compare its internal size.=0D + PolicyEntry =3D (VARIABLE_POLICY_ENTRY*)((UINT8*)InternalCommBuffer = + sizeof(VAR_CHECK_POLICY_COMM_HEADER));=0D + if (PolicyEntry->Version !=3D VARIABLE_POLICY_ENTRY_REVISION ||=0D + PolicyEntry->Size < sizeof(VARIABLE_POLICY_ENTRY) ||=0D + EFI_ERROR(SafeUintnAdd(sizeof(VAR_CHECK_POLICY_COMM_HEADER), Pol= icyEntry->Size, &ExpectedSize)) ||=0D + InternalCommBufferSize < ExpectedSize) {=0D + DEBUG(( DEBUG_INFO, "%a - Bad policy entry contents!\n", __FUNCTIO= N__ ));=0D + PolicyCommmHeader->Result =3D EFI_INVALID_PARAMETER;=0D + break;=0D + }=0D +=0D + PolicyCommmHeader->Result =3D RegisterVariablePolicy( PolicyEntry );= =0D + break;=0D +=0D + case VAR_CHECK_POLICY_COMMAND_DUMP:=0D + // Make sure that we're dealing with a reasonable size.=0D + // This add should be safe because these are fixed sizes so far.=0D + ExpectedSize +=3D sizeof(VAR_CHECK_POLICY_COMM_DUMP_PARAMS) + VAR_CH= ECK_POLICY_MM_DUMP_BUFFER_SIZE;=0D + if (InternalCommBufferSize < ExpectedSize) {=0D + DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNC= TION__, InternalCommBufferSize, ExpectedSize ));=0D + PolicyCommmHeader->Result =3D EFI_INVALID_PARAMETER;=0D + break;=0D + }=0D +=0D + // Now that we know we've got a valid size, we can fill in the rest = of the data.=0D + DumpParamsIn =3D (VAR_CHECK_POLICY_COMM_DUMP_PARAMS*)(InternalPolicy= CommmHeader + 1);=0D + DumpParamsOut =3D (VAR_CHECK_POLICY_COMM_DUMP_PARAMS*)(PolicyCommmHe= ader + 1);=0D +=0D + // If we're requesting the first page, initialize the cache and get = the sizes.=0D + if (DumpParamsIn->PageRequested =3D=3D 0) {=0D + if (mPaginationCache !=3D NULL) {=0D + FreePool (mPaginationCache);=0D + mPaginationCache =3D NULL;=0D + }=0D +=0D + // Determine what the required size is going to be.=0D + DumpParamsOut->TotalSize =3D 0;=0D + DumpParamsOut->PageSize =3D 0;=0D + DumpParamsOut->HasMore =3D FALSE;=0D + SubCommandStatus =3D DumpVariablePolicy (NULL, &TempSize);=0D + if (SubCommandStatus =3D=3D EFI_BUFFER_TOO_SMALL && TempSize > 0) = {=0D + mCurrentPaginationCommand =3D VAR_CHECK_POLICY_COMMAND_DUMP;=0D + mPaginationCacheSize =3D TempSize;=0D + DumpParamsOut->TotalSize =3D TempSize;=0D + mPaginationCache =3D AllocatePool (mPaginationCacheSize);=0D + if (mPaginationCache =3D=3D NULL) {=0D + SubCommandStatus =3D EFI_OUT_OF_RESOURCES;=0D + }=0D + }=0D +=0D + // If we've allocated our pagination cache, we're good to cache.=0D + if (mPaginationCache !=3D NULL) {=0D + SubCommandStatus =3D DumpVariablePolicy (mPaginationCache, &Temp= Size);=0D + }=0D +=0D + // Populate the remaining fields and we can boogie.=0D + if (!EFI_ERROR (SubCommandStatus) && mPaginationCache !=3D NULL) {= =0D + DumpParamsOut->HasMore =3D TRUE;=0D + }=0D + } else if (mPaginationCache !=3D NULL) {=0D + DumpParamsOut->TotalSize =3D (UINT32)mPaginationCacheSize;=0D + DumpOutputBuffer =3D (UINT8*)(DumpParamsOut + 1);=0D +=0D + // Make sure that we don't over-index the cache.=0D + DumpTotalPages =3D mPaginationCacheSize / VAR_CHECK_POLICY_MM_DUMP= _BUFFER_SIZE;=0D + if (mPaginationCacheSize % VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE != =3D 0) {=0D + DumpTotalPages++;=0D + }=0D + if (DumpParamsIn->PageRequested > DumpTotalPages) {=0D + SubCommandStatus =3D EFI_INVALID_PARAMETER;=0D + } else {=0D + // Figure out how far into the page cache we need to go for our = next page.=0D + // We know the blind subtraction won't be bad because we already= checked for page 0.=0D + DumpInputBuffer =3D &mPaginationCache[VAR_CHECK_POLICY_MM_DUMP_B= UFFER_SIZE * (DumpParamsIn->PageRequested - 1)];=0D + TempSize =3D VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE;=0D + // If we're getting the last page, adjust the PageSize.=0D + if (DumpParamsIn->PageRequested =3D=3D DumpTotalPages) {=0D + TempSize =3D mPaginationCacheSize % VAR_CHECK_POLICY_MM_DUMP_B= UFFER_SIZE;=0D + }=0D + CopyMem (DumpOutputBuffer, DumpInputBuffer, TempSize);=0D + DumpParamsOut->PageSize =3D TempSize;=0D + // If we just got the last page, settle up the cache.=0D + if (DumpParamsIn->PageRequested =3D=3D DumpTotalPages) {=0D + DumpParamsOut->HasMore =3D FALSE;=0D + FreePool (mPaginationCache);=0D + mPaginationCache =3D NULL;=0D + mPaginationCacheSize =3D 0;=0D + mCurrentPaginationCommand =3D 0;=0D + // Otherwise, we could do more here.=0D + } else {=0D + DumpParamsOut->HasMore =3D TRUE;=0D + }=0D +=0D + // If we made it this far, we're basically good.=0D + SubCommandStatus =3D EFI_SUCCESS;=0D + }=0D + // If we've requested any other page than 0 and the cache is empty, = we must have timed out.=0D + } else {=0D + DumpParamsOut->TotalSize =3D 0;=0D + DumpParamsOut->PageSize =3D 0;=0D + DumpParamsOut->HasMore =3D FALSE;=0D + SubCommandStatus =3D EFI_TIMEOUT;=0D + }=0D +=0D + // There's currently no use for this, but it shouldn't be hard to im= plement.=0D + PolicyCommmHeader->Result =3D SubCommandStatus;=0D + break;=0D +=0D + case VAR_CHECK_POLICY_COMMAND_LOCK:=0D + PolicyCommmHeader->Result =3D LockVariablePolicy();=0D + break;=0D +=0D + default:=0D + // Mark unknown requested command as EFI_UNSUPPORTED.=0D + DEBUG(( DEBUG_INFO, "%a - Invalid command requested! %d\n", __FUNCTI= ON__, PolicyCommmHeader->Command ));=0D + PolicyCommmHeader->Result =3D EFI_UNSUPPORTED;=0D + break;=0D + }=0D +=0D + DEBUG(( DEBUG_VERBOSE, "%a - Command %d returning %r.\n", __FUNCTION__,= =0D + PolicyCommmHeader->Command, PolicyCommmHeader->Result ));=0D +=0D + return Status;=0D +}=0D +=0D +=0D +/**=0D + Constructor function of VarCheckPolicyLib to register VarCheck handler a= nd=0D + SW MMI handlers.=0D +=0D + @param[in] ImageHandle The firmware allocated handle for the EFI imag= e.=0D + @param[in] SystemTable A pointer to the EFI System Table.=0D +=0D + @retval EFI_SUCCESS The constructor executed correctly.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +VarCheckPolicyLibConstructor (=0D + IN EFI_HANDLE ImageHandle,=0D + IN EFI_SYSTEM_TABLE *SystemTable=0D + )=0D +{=0D + EFI_STATUS Status;=0D + EFI_HANDLE DiscardedHandle;=0D +=0D + // Initialize the business logic with the internal GetVariable handler.= =0D + Status =3D InitVariablePolicyLib( VariableServiceGetVariable );=0D +=0D + // Only proceed with init if the business logic could be initialized.=0D + if (!EFI_ERROR( Status )) {=0D + // Register the VarCheck handler for SetVariable filtering.=0D + // Forward the check to the business logic of the library.=0D + VarCheckLibRegisterSetVariableCheckHandler( ValidateSetVariable );=0D +=0D + // Register the MMI handlers for receiving policy commands.=0D + DiscardedHandle =3D NULL;=0D + Status =3D gMmst->MmiHandlerRegister( VarCheckPolicyLibMmiHandler,=0D + &gVarCheckPolicyLibMmiHandlerGuid,= =0D + &DiscardedHandle );=0D + }=0D + // Otherwise, there's not much we can do.=0D + else {=0D + DEBUG(( DEBUG_ERROR, "%a - Cannot Initialize VariablePolicyLib! %r\n",= __FUNCTION__, Status ));=0D + ASSERT_EFI_ERROR( Status );=0D + }=0D +=0D + return Status;=0D +}=0D 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=0D +This header contains communication definitions that are shared between DXE= =0D +and the MM component of VarCheckPolicy.=0D +=0D +Copyright (c) Microsoft Corporation.=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#ifndef _VAR_CHECK_POLICY_MMI_COMMON_H_=0D +#define _VAR_CHECK_POLICY_MMI_COMMON_H_=0D +=0D +#define VAR_CHECK_POLICY_COMM_SIG SIGNATURE_32('V', 'C', 'P', 'C')= =0D +#define VAR_CHECK_POLICY_COMM_REVISION 1=0D +=0D +#pragma pack(push, 1)=0D +=0D +typedef struct _VAR_CHECK_POLICY_COMM_HEADER {=0D + UINT32 Signature;=0D + UINT32 Revision;=0D + UINT32 Command;=0D + EFI_STATUS Result;=0D +} VAR_CHECK_POLICY_COMM_HEADER;=0D +=0D +typedef struct _VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS {=0D + BOOLEAN State;=0D +} VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS;=0D +=0D +typedef struct _VAR_CHECK_POLICY_COMM_DUMP_PARAMS {=0D + UINT32 PageRequested;=0D + UINT32 TotalSize;=0D + UINT32 PageSize;=0D + BOOLEAN HasMore;=0D +} VAR_CHECK_POLICY_COMM_DUMP_PARAMS;=0D +=0D +#pragma pack(pop)=0D +=0D +// Make sure that we will hold at least the headers.=0D +#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))=0D +#define VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE (VAR_CHECK_POLICY_MM_COMM_= BUFFER_SIZE - \=0D + (OFFSET_OF(EFI_MM_COMM= UNICATE_HEADER, Data) + \=0D + sizeof(VAR_CHECK_POL= ICY_COMM_HEADER) + \=0D + sizeof(VAR_CHECK_POL= ICY_COMM_DUMP_PARAMS)))=0D +STATIC_ASSERT (=0D + VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE < VAR_CHECK_POLICY_MM_COMM_BUFFER_S= IZE,=0D + "an integer underflow may have occurred calculating VAR_CHECK_POLICY_MM_= DUMP_BUFFER_SIZE"=0D + );=0D +=0D +#define VAR_CHECK_POLICY_COMMAND_DISABLE 0x0001=0D +#define VAR_CHECK_POLICY_COMMAND_IS_ENABLED 0x0002=0D +#define VAR_CHECK_POLICY_COMMAND_REGISTER 0x0003=0D +#define VAR_CHECK_POLICY_COMMAND_DUMP 0x0004=0D +#define VAR_CHECK_POLICY_COMMAND_LOCK 0x0005=0D +=0D +#endif // _VAR_CHECK_POLICY_MMI_COMMON_H_=0D 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=0D +# This is an instance of a VarCheck lib that leverages the business logic = behind=0D +# the VariablePolicy code to make its decisions.=0D +#=0D +# Copyright (c) Microsoft Corporation.=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010005=0D + BASE_NAME =3D VarCheckPolicyLib=0D + FILE_GUID =3D 9C28A48F-C884-4B1F-8B95-DEF125448023= =0D + MODULE_TYPE =3D DXE_RUNTIME_DRIVER=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D NULL|DXE_RUNTIME_DRIVER DXE_SMM_DRIVE= R=0D + CONSTRUCTOR =3D VarCheckPolicyLibConstructor=0D +=0D +=0D +[Sources]=0D + VarCheckPolicyLib.c=0D +=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + MdeModulePkg/MdeModulePkg.dec=0D +=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + DebugLib=0D + BaseMemoryLib=0D + DxeServicesLib=0D + MemoryAllocationLib=0D + VarCheckLib=0D + VariablePolicyLib=0D + VariablePolicyHelperLib=0D + SafeIntLib=0D + MmServicesTableLib=0D +=0D +=0D +[Guids]=0D + gVarCheckPolicyLibMmiHandlerGuid ## CONSUME ## Used to register f= or MM Communication events.=0D 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=0D +// VarCheckPolicyLib.uni=0D +//=0D +// Copyright (c) Microsoft Corporation.=0D +// SPDX-License-Identifier: BSD-2-Clause-Patent=0D +//=0D +// **/=0D +=0D +=0D +#string STR_MODULE_ABSTRACT #language en-US "NULL library impl= ementation that conforms to the VarCheck interface to allow VariablePolicy = engine to enforce policies"=0D +=0D +#string STR_MODULE_DESCRIPTION #language en-US "NULL library impl= ementation that conforms to the VarCheck interface to allow VariablePolicy = engine to enforce policies"=0D 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=0D gEdkiiEndOfS3ResumeGuid =3D { 0x96f5296d, 0x05f7, 0x4f3c, {0x84, 0x67, 0= xe4, 0x56, 0x89, 0x0e, 0x0c, 0xb5 } }=0D =0D + ## Used (similar to Variable Services) to communicate policies to the en= forcement engine.=0D + # {DA1B0D11-D1A7-46C4-9DC9-F3714875C6EB}=0D + gVarCheckPolicyLibMmiHandlerGuid =3D { 0xda1b0d11, 0xd1a7, 0x46c4, { 0x9= d, 0xc9, 0xf3, 0x71, 0x48, 0x75, 0xc6, 0xeb }}=0D +=0D ## Include/Guid/S3SmmInitDone.h=0D gEdkiiS3SmmInitDoneGuid =3D { 0x8f9d4825, 0x797d, 0x48fc, { 0x84, 0x71, = 0x84, 0x50, 0x25, 0x79, 0x2e, 0xf6 } }=0D =0D 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=0D MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf=0D MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf=0D + MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf=0D MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf=0D MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf=0D MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf=0D @@ -458,6 +459,7 @@ [Components.IA32, Components.X64] MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf=0D MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf {=0D =0D + NULL|MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf=0D NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf=0D NULL|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf=0D NULL|MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf=0D --=20 2.28.0.windows.1