From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (NAM10-BN7-obe.outbound.protection.outlook.com [40.92.40.93]) by mx.groups.io with SMTP id smtpd.web12.1207.1589266035113879433 for ; Mon, 11 May 2020 23:47:15 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@outlook.com header.s=selector1 header.b=b2GTR8/i; spf=pass (domain: outlook.com, ip: 40.92.40.93, mailfrom: michael.kubacki@outlook.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=IwNStcPwv3dCJ20HoEpn8x474hlXFr5++5QOKd8tpYFqnJmt5DL/9hHh3Fu3VjXrW79I6/LcZXNFFVy0101HYMtbPj8m54bwE8xCuKAbQ8aq8y07lEH6IiF6cQHFI5NxxZgQVmwobBt6t+e8nFlSfxuGcHKJnV2GlhNrcSupCD35VKFVnFNZWbdEhFhP9Mfi1SlpVOrn9EX0TiCF9iBzRyvV7Oc6X9aQG0yu5v+lEKtj4wNAhV0+JvXBXd+Y+14AczJYBX2/vnZWu+veZCSbN7dVzcz6v4OqPYn3DDx0x3KMXbKdCtXZ2QxXeJ0Kgq+WCc9ZAc8OWj2xfRbyLPcFQg== 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=wqbhXDqGQShrBOqi0Cc6zU+Hhh594aKrjGZyrWnp7ik=; b=JcptoNfVbsrbw6ICfftiEd/1OqlXSML6Qo/3fOcsWszKPOdBBHRKaDvhcZU4Q88bz03Nrf9aeJhUw5+MFM2G2OeHaXz1F5sa/+Ma5fUWW1OVHxeQl0rhjODiuuR6TaqsXj9yFZzsUpU9v5XNNiz6kXdIU4U/77IDv9rqbxQCIvDz2Vi/0Tq2iIRNh9QMAaJFgPC3+T1dBy0gMhPudvpJWFcdbtnA4Jl6A00v99aHtGcSSYg4GSydWFghP1gTVVxUMhcE4cDhxN3yS/T8LpY4dkfS+lJl+N/Mx4DROa4zjoGZkPk5VEc3fIHb3zfCFnjNGuoTO0/gPA6w4WyKjrXm7Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=outlook.com; dmarc=pass action=none header.from=outlook.com; dkim=pass header.d=outlook.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=outlook.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=wqbhXDqGQShrBOqi0Cc6zU+Hhh594aKrjGZyrWnp7ik=; b=b2GTR8/iMcYm8Qmtn7Inoy5yz2HKUExFGsYxYyEqZ7rbNP4DHKwD7McLZFp+tuji5L1sQ8EX6tsAIU3Hkzri3KzZ+vhA/zDjAU/r1eVFPA0LKX41/7jPsBujcv45ZAqQdJrCHPpjpDrXOmaBgloa1Y/GVZtFnaGEYSNaX+0XPgCieiy9lDuDFJWFgI9mdiLBlaFsxfVDSLffGdDp6pgn9YgdUboatMXIyLpK6WKj61zkScoKqo4lQdNyxdYNN6cRmYeYm4wyeTZuquSoY6xLcbE01BPWoPREhO4Z0xUQwGSwnFNpQ59qY2iQEvRwNSuUlMfEGm9C1u9VzM5+i3M73Q== Received: from BN7NAM10FT010.eop-nam10.prod.protection.outlook.com (2a01:111:e400:7e8f::4a) by BN7NAM10HT037.eop-nam10.prod.protection.outlook.com (2a01:111:e400:7e8f::225) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.27; Tue, 12 May 2020 06:47:13 +0000 Received: from MWHPR07MB3440.namprd07.prod.outlook.com (2a01:111:e400:7e8f::4b) by BN7NAM10FT010.mail.protection.outlook.com (2a01:111:e400:7e8f::421) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.27 via Frontend Transport; Tue, 12 May 2020 06:47:13 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:998A4622FC00DACBA57FDA8E6E01B2EA44F4BFB7504416242D8BA6C95866DD37;UpperCasedChecksum:965D26094A7180868A0862A9E6375FCED294F4D7DE78E0EBB44BF5AF6BA84697;SizeAsReceived:7762;Count:49 Received: from MWHPR07MB3440.namprd07.prod.outlook.com ([fe80::bcc9:271b:20db:52e3]) by MWHPR07MB3440.namprd07.prod.outlook.com ([fe80::bcc9:271b:20db:52e3%6]) with mapi id 15.20.2979.033; Tue, 12 May 2020 06:47:13 +0000 From: "Michael Kubacki" To: devel@edk2.groups.io Cc: Jian J Wang , Hao A Wu , Liming Gao Subject: [PATCH v2 04/12] MdeModulePkg: Define the VarCheckPolicyLib and SMM interface Date: Mon, 11 May 2020 23:46:27 -0700 Message-ID: X-Mailer: git-send-email 2.16.3.windows.1 In-Reply-To: <20200512064635.14640-1-michael.kubacki@outlook.com> References: <20200512064635.14640-1-michael.kubacki@outlook.com> X-ClientProxiedBy: MW2PR16CA0022.namprd16.prod.outlook.com (2603:10b6:907::35) To MWHPR07MB3440.namprd07.prod.outlook.com (2603:10b6:301:69::28) Return-Path: michael.kubacki@outlook.com X-Microsoft-Original-Message-ID: <20200512064635.14640-5-michael.kubacki@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from localhost.localdomain (2001:4898:80e8:b:422:2743:5e95:81bb) by MW2PR16CA0022.namprd16.prod.outlook.com (2603:10b6:907::35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.27 via Frontend Transport; Tue, 12 May 2020 06:47:13 +0000 X-Mailer: git-send-email 2.16.3.windows.1 X-Microsoft-Original-Message-ID: <20200512064635.14640-5-michael.kubacki@outlook.com> X-TMN: [AZqcIzqiYd38rDhEX/BBT5g6EtWDva3w3/yb/xwghK3vntlq2aHK/duYne0Q4tC6] X-MS-PublicTrafficType: Email X-IncomingHeaderCount: 49 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-Correlation-Id: 58083e9d-bd13-4dc6-57cc-08d7f6404d79 X-MS-TrafficTypeDiagnostic: BN7NAM10HT037: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: BH5uw8M0rQP+heZ/FgLaOvyKdAedNiRHZ1jTYrzxUyOmZQWvIBMwCwHBkIWETWaTzmvFt3rteslyq8pLL9IFhuwSvzxFlJH0up7PpBfemP6yXn75F4YOanRYOpSlLnS+XRh2uGSzTDkb1JlFIvyLYwNItegbArUTdJmZb90v2cu66UUgGfPDh4ZAz3hE9nja+jtWIKdCpH50DNaM9SMUh2OYl4wu8nw2+40XKioEQYk8+VtZhTl1+x4Ma1qp89P+ X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:0;SRV:;IPV:NLI;SFV:NSPM;H:MWHPR07MB3440.namprd07.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:;DIR:OUT;SFP:1901; X-MS-Exchange-AntiSpam-MessageData: qx4a8Q8iJBqHZjIIyDSxfZCdvAZ1BSyH+H2FDkJcFmj0ImaE92dr5j0Zt6Ss9sTx93UBqMuLpbK7+GIevzaHOQA5Zz25rri4yXVWTKwacYe7YM3Heb7gw55CJgXmE6IydN1B3BwTlg9KQCeuZ1FQGHy9jqTFWQ0WWIJIK/rM7L+YwRFYOQNsjxntJd7h8nWQiG7+LFZpxwTAi1WwOOIFZg== X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 58083e9d-bd13-4dc6-57cc-08d7f6404d79 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 May 2020 06:47:13.6521 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-FromEntityHeader: Internet X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN7NAM10HT037 Content-Type: text/plain From: Bret Barkelew https://bugzilla.tianocore.org/show_bug.cgi?id=2522 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 Signed-off-by: Michael Kubacki --- MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c | 318 ++++++++++++++++++++ MdeModulePkg/Include/Guid/VarCheckPolicyMmi.h | 54 ++++ MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf | 44 +++ MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.uni | 12 + MdeModulePkg/MdeModulePkg.dec | 4 + MdeModulePkg/MdeModulePkg.dsc | 2 + 6 files changed, 434 insertions(+) diff --git a/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c new file mode 100644 index 000000000000..d5775d7dd068 --- /dev/null +++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.c @@ -0,0 +1,318 @@ +/** @file -- VarCheckPolicyLib.c +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 + +**/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +//================================================ +// 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. +//================================================ +EFI_STATUS +EFIAPI +VariableServiceGetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data + ); + + +/** + MM Communication Handler to recieve commands from the DXE protocol for + Variable Policies. This communication channel is used to register new policies + and poll and toggle the enforcement of variable policies. + + @param[in] DispatchHandle All parameters standard to MM communications convention. + @param[in] RegisterContex All parameters standard to MM communications convention. + @param[in,out] CommBuffer All parameters standard to MM communications convention. + @param[in,out] CommBufferSize All parameters standard to MM communications 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 + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_STATUS SubCommandStatus; + VAR_CHECK_POLICY_COMM_HEADER *PolicyCommmHeader; + VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS *IsEnabledParams; + VAR_CHECK_POLICY_COMM_DUMP_PARAMS *DumpParams; + UINT8 *DumpInputBuffer; + UINT8 *DumpOutputBuffer; + UINTN DumpTotalPages; + VARIABLE_POLICY_ENTRY *PolicyEntry; + UINTN ExpectedSize; + // Pagination Cache Variables + static UINT8 *PaginationCache = NULL; + static UINTN PaginationCacheSize = 0; + static UINT32 CurrentPaginationCommand = 0; + + // + // Validate some input parameters. + // + // If either of the pointers are NULL, we can't proceed. + if (CommBuffer == NULL || CommBufferSize == NULL) { + DEBUG(( DEBUG_INFO, "%a - Invalid comm buffer pointers!\n", __FUNCTION__ )); + return EFI_INVALID_PARAMETER; + } + // If the size does not meet a minimum threshold, we cannot proceed. + ExpectedSize = sizeof(VAR_CHECK_POLICY_COMM_HEADER); + if (*CommBufferSize < ExpectedSize) { + DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNCTION__, *CommBufferSize, ExpectedSize )); + return EFI_INVALID_PARAMETER; + } + // Check the revision and the signature of the comm header. + PolicyCommmHeader = CommBuffer; + if (PolicyCommmHeader->Signature != VAR_CHECK_POLICY_COMM_SIG || + PolicyCommmHeader->Revision != VAR_CHECK_POLICY_COMM_REVISION) { + DEBUG(( DEBUG_INFO, "%a - Signature or revision are incorrect!\n", __FUNCTION__ )); + // We have verified the buffer is not null and have enough size to hold Result field. + PolicyCommmHeader->Result = EFI_INVALID_PARAMETER; + return EFI_SUCCESS; + } + + // If we're in the middle of a paginated dump and any other command is sent, + // pagination cache must be cleared. + if (PaginationCache != NULL && PolicyCommmHeader->Command != CurrentPaginationCommand) { + FreePool (PaginationCache); + PaginationCache = NULL; + PaginationCacheSize = 0; + CurrentPaginationCommand = 0; + } + + // + // Now we can process the command as it was sent. + // + PolicyCommmHeader->Result = EFI_ABORTED; // Set a default return for incomplete commands. + switch(PolicyCommmHeader->Command) { + case VAR_CHECK_POLICY_COMMAND_DISABLE: + PolicyCommmHeader->Result = 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 += sizeof(VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS); + if (*CommBufferSize < ExpectedSize) { + DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNCTION__, *CommBufferSize, ExpectedSize )); + PolicyCommmHeader->Result = EFI_INVALID_PARAMETER; + break; + } + + // Now that we know we've got a valid size, we can fill in the rest of the data. + IsEnabledParams = (VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS*)((UINT8*)CommBuffer + sizeof(VAR_CHECK_POLICY_COMM_HEADER)); + IsEnabledParams->State = IsVariablePolicyEnabled(); + PolicyCommmHeader->Result = 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 += sizeof(VARIABLE_POLICY_ENTRY); + if (*CommBufferSize < ExpectedSize) { + DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNCTION__, *CommBufferSize, ExpectedSize )); + PolicyCommmHeader->Result = 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 = (VARIABLE_POLICY_ENTRY*)((UINT8*)CommBuffer + sizeof(VAR_CHECK_POLICY_COMM_HEADER)); + if (PolicyEntry->Version != VARIABLE_POLICY_ENTRY_REVISION || + PolicyEntry->Size < sizeof(VARIABLE_POLICY_ENTRY) || + EFI_ERROR(SafeUintnAdd(sizeof(VAR_CHECK_POLICY_COMM_HEADER), PolicyEntry->Size, &ExpectedSize)) || + *CommBufferSize < ExpectedSize) { + DEBUG(( DEBUG_INFO, "%a - Bad policy entry contents!\n", __FUNCTION__ )); + PolicyCommmHeader->Result = EFI_INVALID_PARAMETER; + break; + } + + PolicyCommmHeader->Result = 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 += sizeof(VAR_CHECK_POLICY_COMM_DUMP_PARAMS) + VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE; + if (*CommBufferSize < ExpectedSize) { + DEBUG(( DEBUG_INFO, "%a - Bad comm buffer size! %d < %d\n", __FUNCTION__, *CommBufferSize, ExpectedSize )); + PolicyCommmHeader->Result = EFI_INVALID_PARAMETER; + break; + } + + // Now that we know we've got a valid size, we can fill in the rest of the data. + DumpParams = (VAR_CHECK_POLICY_COMM_DUMP_PARAMS*)(PolicyCommmHeader + 1); + + // If we're requesting the first page, initialize the cache and get the sizes. + if (DumpParams->PageRequested == 0) { + if (PaginationCache != NULL) { + FreePool (PaginationCache); + PaginationCache = NULL; + } + + // Determine what the required size is going to be. + DumpParams->TotalSize = 0; + DumpParams->PageSize = 0; + DumpParams->HasMore = FALSE; + SubCommandStatus = DumpVariablePolicy (NULL, &DumpParams->TotalSize); + if (SubCommandStatus == EFI_BUFFER_TOO_SMALL && DumpParams->TotalSize > 0) { + CurrentPaginationCommand = VAR_CHECK_POLICY_COMMAND_DUMP; + PaginationCacheSize = DumpParams->TotalSize; + PaginationCache = AllocatePool (PaginationCacheSize); + if (PaginationCache == NULL) { + SubCommandStatus = EFI_OUT_OF_RESOURCES; + } + } + + // If we've allocated our pagination cache, we're good to cache. + if (PaginationCache != NULL) { + SubCommandStatus = DumpVariablePolicy (PaginationCache, &DumpParams->TotalSize); + } + + // Populate the remaining fields and we can boogie. + if (!EFI_ERROR (SubCommandStatus) && PaginationCache != NULL) { + DumpParams->HasMore = TRUE; + } + } + else if (PaginationCache != NULL) { + DumpParams->TotalSize = (UINT32)PaginationCacheSize; + DumpParams->PageSize = VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE; + DumpOutputBuffer = (UINT8*)(DumpParams + 1); + + // Make sure that we don't over-index the cache. + DumpTotalPages = PaginationCacheSize / DumpParams->PageSize; + if (PaginationCacheSize % DumpParams->PageSize) DumpTotalPages++; + if (DumpParams->PageRequested > DumpTotalPages) { + SubCommandStatus = 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 = &PaginationCache[DumpParams->PageSize * (DumpParams->PageRequested - 1)]; + // If we're getting the last page, adjust the PageSize. + if (DumpParams->PageRequested == DumpTotalPages) { + DumpParams->PageSize = PaginationCacheSize % DumpParams->PageSize; + } + CopyMem (DumpOutputBuffer, DumpInputBuffer, DumpParams->PageSize); + // If we just got the last page, settle up the cache. + if (DumpParams->PageRequested == DumpTotalPages) { + DumpParams->HasMore = FALSE; + FreePool (PaginationCache); + PaginationCache = NULL; + PaginationCacheSize = 0; + CurrentPaginationCommand = 0; + } + // Otherwise, we could do more here. + else { + DumpParams->HasMore = TRUE; + } + + // If we made it this far, we're basically good. + SubCommandStatus = EFI_SUCCESS; + } + } + // If we've requested any other page than 0 and the cache is empty, we must have timed out. + else { + DumpParams->TotalSize = 0; + DumpParams->PageSize = 0; + DumpParams->HasMore = FALSE; + SubCommandStatus = EFI_TIMEOUT; + } + + // There's currently no use for this, but it shouldn't be hard to implement. + PolicyCommmHeader->Result = SubCommandStatus; + break; + + case VAR_CHECK_POLICY_COMMAND_LOCK: + PolicyCommmHeader->Result = LockVariablePolicy(); + break; + + default: + // Mark unknown requested command as EFI_UNSUPPORTED. + DEBUG(( DEBUG_INFO, "%a - Invalid command requested! %d\n", __FUNCTION__, PolicyCommmHeader->Command )); + PolicyCommmHeader->Result = 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 and + SW MMI handlers. + + @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 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 = 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 = NULL; + Status = 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/Include/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_COMMUNICATE_HEADER, Data) + sizeof (VAR_CHECK_POLICY_COMM_HEADER) + EFI_PAGES_TO_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_COMMUNICATE_HEADER, Data) + \ + sizeof(VAR_CHECK_POLICY_COMM_HEADER) + \ + sizeof(VAR_CHECK_POLICY_COMM_DUMP_PARAMS))) +STATIC_ASSERT ( + VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE < VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE, + "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..7c407e254330 --- /dev/null +++ b/MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf @@ -0,0 +1,44 @@ +## @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 = 0x00010005 + BASE_NAME = VarCheckPolicyLib + FILE_GUID = 9C28A48F-C884-4B1F-8B95-DEF125448023 + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = NULL|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER + CONSTRUCTOR = 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 for 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 implementation that conforms to the VarCheck interface to allow VariablePolicy engine to enforce policies" + +#string STR_MODULE_DESCRIPTION #language en-US "NULL library implementation that conforms to the VarCheck interface to allow VariablePolicy engine to enforce policies" diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index d66002fc9651..ecfa87ffa81d 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -385,6 +385,10 @@ ## Include/Guid/EndofS3Resume.h gEdkiiEndOfS3ResumeGuid = { 0x96f5296d, 0x05f7, 0x4f3c, {0x84, 0x67, 0xe4, 0x56, 0x89, 0x0e, 0x0c, 0xb5 } } + ## Used (similar to Variable Services) to communicate policies to the enforcement engine. + # {DA1B0D11-D1A7-46C4-9DC9-F3714875C6EB} + gVarCheckPolicyLibMmiHandlerGuid = { 0xda1b0d11, 0xd1a7, 0x46c4, { 0x9d, 0xc9, 0xf3, 0x71, 0x48, 0x75, 0xc6, 0xeb }} + ## Include/Guid/S3SmmInitDone.h gEdkiiS3SmmInitDoneGuid = { 0x8f9d4825, 0x797d, 0x48fc, { 0x84, 0x71, 0x84, 0x50, 0x25, 0x79, 0x2e, 0xf6 } } diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 37795b9e4f58..f0a75a3b337b 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -313,6 +313,7 @@ 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 @@ 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 -- 2.16.3.windows.1