From nobody Wed May 15 19:16:36 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+113757+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+113757+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1705086962; cv=none; d=zohomail.com; s=zohoarc; b=fJz1qzVYxJNwnqMMLAz/4dy0g5WTIxBckTa4cHtIO9jZvWYFHwR2hkWsvI4DJlp3x+2UOD5aA1lLNGpXjkZ4jZ6bd2z7+ty8RqHpqRqJuAvMBdP1Fcxjf+A02D/DggPJtjYjiXyidauhapBFHeMOByO/mVb/rO1bHj2+xb/UuM8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1705086962; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=VPHSHOptWowlzOCnLq+NEXps2vkTupAV+//nCv94vOQ=; b=L9aZDiZKngFrwU4fFo9GT0/RRh6hyL94xso94yKztZow2NLR5Gc/47N9XRsj5IjL5foJJor2vHOUj8uYiC9oLdSDGs2MDjusmMRxcqeNaWKEGNk0JR6bPKZEDzZl+HjpKt2TnH7SEC853xbO/q16kzMK+q20/2hxtfIif9keLLg= 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+113757+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1705086962803490.4868596906259; Fri, 12 Jan 2024 11:16:02 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=6ShZkVz9cBf0nsc9gUNtxPIPwDpvh9Ew7LHXQ0KFgLE=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1705086962; v=1; b=SJbSpT3m+3lrAnKWv1dQXIArY3NhMM5l9XAGjr73/CAz+1+3lwngWbdmJ58e8+POHU+Ar51I L5vl5spiDBDNiX/hvB481k5H3vVTfipq6OD7blCGDJjk1M7mMTMu/MghcmNCV3yOIWvlQgbUfwI zO7JfSjQ2ZQH4oDSylcEgshw= X-Received: by 127.0.0.2 with SMTP id rAcYYY1788612x0Uf31Uqk0G; Fri, 12 Jan 2024 11:16:02 -0800 X-Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) by mx.groups.io with SMTP id smtpd.web11.18610.1704997014047649083 for ; Thu, 11 Jan 2024 10:16:54 -0800 X-Received: by mail-pl1-f178.google.com with SMTP id d9443c01a7336-1d3e8a51e6bso44965025ad.3 for ; Thu, 11 Jan 2024 10:16:54 -0800 (PST) X-Gm-Message-State: T8qnPqoyM8A3dM7eMNZMAGm3x1787277AA= X-Google-Smtp-Source: AGHT+IHzj/eKUDrdzsMSrCcGUnCxNcaGLdhT74jS77svIlZkEqUXTci1nYB13emAB2QPQ6YjTX6BiA== X-Received: by 2002:a17:902:e743:b0:1d3:fe01:17ec with SMTP id p3-20020a170902e74300b001d3fe0117ecmr174314plf.18.1704997012062; Thu, 11 Jan 2024 10:16:52 -0800 (PST) X-Received: from localhost.localdomain ([131.107.1.208]) by smtp.gmail.com with ESMTPSA id kd13-20020a17090313cd00b001d4752f5403sm1453414plb.206.2024.01.11.10.16.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Jan 2024 10:16:51 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: "Douglas Flick [MSFT]" , Jiewen Yao Subject: [edk2-devel] [PATCH 1/6] SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4117 - CVE 2022-36763 Date: Thu, 11 Jan 2024 10:16:01 -0800 Message-ID: <991051b5e7572f9bd6abacef48275a3511e5a0c5.1704996627.git.doug.edk2@gmail.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: 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,dougflick@microsoft.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1705086964274100006 Content-Type: text/plain; charset="utf-8" This commit contains the patch files and tests for DxeTpm2MeasureBootLib CVE 2022-36763. Cc: Jiewen Yao Signed-off-by: Doug Flick [MSFT] --- SecurityPkg/Test/SecurityPkgHostTest.dsc | 1 + .../DxeTpm2MeasureBootLib.inf | 4 +- ...Tpm2MeasureBootLibSanitizationTestHost.inf | 28 ++ .../DxeTpm2MeasureBootLibSanitization.h | 113 +++++++ .../DxeTpm2MeasureBootLib.c | 75 +++-- .../DxeTpm2MeasureBootLibSanitization.c | 275 ++++++++++++++++ .../DxeTpm2MeasureBootLibSanitizationTest.c | 303 ++++++++++++++++++ SecurityPkg/SecurityPkg.ci.yaml | 1 + 8 files changed, 767 insertions(+), 33 deletions(-) create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitT= est/DxeTpm2MeasureBootLibSanitizationTestHost.inf create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2Measur= eBootLibSanitization.h create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2Measur= eBootLibSanitization.c create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitT= est/DxeTpm2MeasureBootLibSanitizationTest.c diff --git a/SecurityPkg/Test/SecurityPkgHostTest.dsc b/SecurityPkg/Test/Se= curityPkgHostTest.dsc index ad5b4fc350ea..788c1ab6fec6 100644 --- a/SecurityPkg/Test/SecurityPkgHostTest.dsc +++ b/SecurityPkg/Test/SecurityPkgHostTest.dsc @@ -26,6 +26,7 @@ [Components] SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtect= ionLib.inf SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/Moc= kPlatformPKProtectionLib.inf + SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2Measur= eBootLibSanitizationTestHost.inf =20 # # Build SecurityPkg HOST_APPLICATION Tests diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLi= b.inf b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf index 6dca79a20c93..28995f438de6 100644 --- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf +++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf @@ -37,6 +37,8 @@ [Defines] =20 [Sources] DxeTpm2MeasureBootLib.c + DxeTpm2MeasureBootLibSanitization.c + DxeTpm2MeasureBootLibSanitization.h =20 [Packages] MdePkg/MdePkg.dec @@ -46,6 +48,7 @@ [Packages] =20 [LibraryClasses] BaseMemoryLib + SafeIntLib DebugLib MemoryAllocationLib DevicePathLib @@ -65,4 +68,3 @@ [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES - diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/Dxe= Tpm2MeasureBootLibSanitizationTestHost.inf b/SecurityPkg/Library/DxeTpm2Mea= sureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf new file mode 100644 index 000000000000..2999aa2a44e0 --- /dev/null +++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2Mea= sureBootLibSanitizationTestHost.inf @@ -0,0 +1,28 @@ +## @file +# This file builds the unit tests for DxeTpm2MeasureBootLib +# +# Copyright (C) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010006 + BASE_NAME =3D DxeTpm2MeasuredBootLibTest + FILE_GUID =3D 144d757f-d423-484e-9309-a23695fad5bd + MODULE_TYPE =3D HOST_APPLICATION + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D main + +[Sources] + DxeTpm2MeasureBootLibSanitizationTest.c + ../DxeTpm2MeasureBootLibSanitization.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + UnitTestLib + PrintLib + SafeIntLib diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLi= bSanitization.h b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureB= ootLibSanitization.h new file mode 100644 index 000000000000..048b73898744 --- /dev/null +++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSaniti= zation.h @@ -0,0 +1,113 @@ +/** @file + This file includes the function prototypes for the sanitization function= s. + + These are those functions: + + DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF ima= ge content + read is within the image buffer. + + Tcg2MeasureGptTable() function will receive untrusted GPT partition tabl= e, and parse + partition data carefully. + + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ +#define DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ + +#include +#include +#include +#include +#include + +/** + This function will validate the EFI_PARTITION_TABLE_HEADER structure is = safe to parse + However this function will not attempt to verify the validity of the GPT= partition + It will check the following: + - Signature + - Revision + - AlternateLBA + - FirstUsableLBA + - LastUsableLBA + - PartitionEntryLBA + - NumberOfPartitionEntries + - SizeOfPartitionEntry + - BlockIo + + @param[in] PrimaryHeader + Pointer to the EFI_PARTITION_TABLE_HEADER structure. + + @param[in] BlockIo + Pointer to the EFI_BLOCK_IO_PROTOCOL structure. + + @retval EFI_SUCCESS + The EFI_PARTITION_TABLE_HEADER structure is valid. + + @retval EFI_INVALID_PARAMETER + The EFI_PARTITION_TABLE_HEADER structure is invalid. +**/ +EFI_STATUS +EFIAPI +SanitizeEfiPartitionTableHeader ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo + ); + +/** + This function will validate that the allocation size from the primary he= ader is sane + It will check the following: + - AllocationSize does not overflow + + @param[in] PrimaryHeader + Pointer to the EFI_PARTITION_TABLE_HEADER structure. + + @param[out] AllocationSize + Pointer to the allocation size. + + @retval EFI_SUCCESS + The allocation size is valid. + + @retval EFI_OUT_OF_RESOURCES + The allocation size is invalid. +**/ +EFI_STATUS +EFIAPI +SanitizePrimaryHeaderAllocationSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + OUT UINT32 *AllocationSize + ); + +/** + This function will validate that the Gpt Event Size calculated from the = primary header is sane + It will check the following: + - EventSize does not overflow + + Important: This function includes the entire length of the allocated spa= ce, including + (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) . When hashing the= buffer allocated with this + size, the caller must subtract the size of the (sizeof (EFI_TCG2_EVENT) = - sizeof (Tcg2Event->Event)) + from the size of the buffer before hashing. + + @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER str= ucture. + @param[in] NumberOfPartition - Number of partitions. + @param[out] EventSize - Pointer to the event size. + + @retval EFI_SUCCESS + The event size is valid. + + @retval EFI_OUT_OF_RESOURCES + Overflow would have occurred. + + @retval EFI_INVALID_PARAMETER + One of the passed parameters was invalid. +**/ +EFI_STATUS +SanitizePrimaryHeaderGptEventSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN UINTN NumberOfPartition, + OUT UINT32 *EventSize + ); + +#endif // DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLi= b.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c index 36a256a7af50..0475103d6ef8 100644 --- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c @@ -20,6 +20,8 @@ Copyright (c) 2013 - 2018, Intel Corporation. All rights = reserved.
(C) Copyright 2015 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent =20 +Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ =20 #include @@ -44,6 +46,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include =20 +#include "DxeTpm2MeasureBootLibSanitization.h" + typedef struct { EFI_TCG2_PROTOCOL *Tcg2Protocol; EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol; @@ -144,10 +148,11 @@ Tcg2MeasureGptTable ( EFI_TCG2_EVENT *Tcg2Event; EFI_CC_EVENT *CcEvent; EFI_GPT_DATA *GptData; - UINT32 EventSize; + UINT32 TcgEventSize; EFI_TCG2_PROTOCOL *Tcg2Protocol; EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol; EFI_CC_MR_INDEX MrIndex; + UINT32 AllocSize; =20 if (mTcg2MeasureGptCount > 0) { return EFI_SUCCESS; @@ -195,25 +200,22 @@ Tcg2MeasureGptTable ( BlockIo->Media->BlockSize, (UINT8 *)PrimaryHeader ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed to Read Partition Table Header!\n")); + if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (Pr= imaryHeader, BlockIo))) { + DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid= Partition Table Header!\n")); FreePool (PrimaryHeader); return EFI_DEVICE_ERROR; } =20 - // - // PrimaryHeader->SizeOfPartitionEntry should not be zero - // - if (PrimaryHeader->SizeOfPartitionEntry =3D=3D 0) { - DEBUG ((DEBUG_ERROR, "SizeOfPartitionEntry should not be zero!\n")); - FreePool (PrimaryHeader); - return EFI_BAD_BUFFER_SIZE; - } - // // Read the partition entry. // - EntryPtr =3D (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntr= ies * PrimaryHeader->SizeOfPartitionEntry); + Status =3D SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSiz= e); + if (EFI_ERROR (Status)) { + FreePool (PrimaryHeader); + return EFI_BAD_BUFFER_SIZE; + } + + EntryPtr =3D (UINT8 *)AllocatePool (AllocSize); if (EntryPtr =3D=3D NULL) { FreePool (PrimaryHeader); return EFI_OUT_OF_RESOURCES; @@ -223,7 +225,7 @@ Tcg2MeasureGptTable ( DiskIo, BlockIo->Media->MediaId, MultU64x32 (PrimaryHeader->PartitionEntryLBA, BlockIo= ->Media->BlockSize), - PrimaryHeader->NumberOfPartitionEntries * PrimaryHead= er->SizeOfPartitionEntry, + AllocSize, EntryPtr ); if (EFI_ERROR (Status)) { @@ -248,16 +250,21 @@ Tcg2MeasureGptTable ( // // Prepare Data for Measurement (CcProtocol and Tcg2Protocol) // - EventSize =3D (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitio= ns) - + NumberOfPartition * PrimaryHeader->SizeOfPartitio= nEntry); - EventPtr =3D (UINT8 *)AllocateZeroPool (EventSize + sizeof (EFI_TCG2_EVE= NT) - sizeof (Tcg2Event->Event)); + Status =3D SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPar= tition, &TcgEventSize); + if (EFI_ERROR (Status)) { + FreePool (PrimaryHeader); + FreePool (EntryPtr); + return EFI_DEVICE_ERROR; + } + + EventPtr =3D (UINT8 *)AllocateZeroPool (TcgEventSize); if (EventPtr =3D=3D NULL) { Status =3D EFI_OUT_OF_RESOURCES; goto Exit; } =20 Tcg2Event =3D (EFI_TCG2_EVENT *)EventPtr; - Tcg2Event->Size =3D EventSize + sizeof (EFI_TCG2_EVENT) = - sizeof (Tcg2Event->Event); + Tcg2Event->Size =3D TcgEventSize; Tcg2Event->Header.HeaderSize =3D sizeof (EFI_TCG2_EVENT_HEADER); Tcg2Event->Header.HeaderVersion =3D EFI_TCG2_EVENT_HEADER_VERSION; Tcg2Event->Header.PCRIndex =3D 5; @@ -310,7 +317,7 @@ Tcg2MeasureGptTable ( CcProtocol, 0, (EFI_PHYSICAL_ADDRESS)(UINTN)(= VOID *)GptData, - (UINT64)EventSize, + (UINT64)TcgEventSize - OFFSET_= OF (EFI_TCG2_EVENT, Event), CcEvent ); if (!EFI_ERROR (Status)) { @@ -326,7 +333,7 @@ Tcg2MeasureGptTable ( Tcg2Protocol, 0, (EFI_PHYSICAL_ADDRESS)(UINTN)(VOID *)GptData, - (UINT64)EventSize, + (UINT64)TcgEventSize - OFFSET_OF (EFI_TCG2_E= VENT, Event), Tcg2Event ); if (!EFI_ERROR (Status)) { @@ -443,11 +450,13 @@ Tcg2MeasurePeImage ( Tcg2Event->Header.PCRIndex =3D 2; break; default: - DEBUG (( - DEBUG_ERROR, - "Tcg2MeasurePeImage: Unknown subsystem type %d", - ImageType - )); + DEBUG ( + ( + DEBUG_ERROR, + "Tcg2MeasurePeImage: Unknown subsystem type %d", + ImageType + ) + ); goto Finish; } =20 @@ -515,7 +524,7 @@ Finish: =20 @param MeasureBootProtocols Pointer to the located measure boot protoc= ol instances. =20 - @retval EFI_SUCCESS Sucessfully locate the measure boot protoc= ol instances (at least one instance). + @retval EFI_SUCCESS Successfully locate the measure boot proto= col instances (at least one instance). @retval EFI_UNSUPPORTED Measure boot is not supported. **/ EFI_STATUS @@ -646,12 +655,14 @@ DxeTpm2MeasureBootHandler ( return EFI_SUCCESS; } =20 - DEBUG (( - DEBUG_INFO, - "Tcg2Protocol =3D %p, CcMeasurementProtocol =3D %p\n", - MeasureBootProtocols.Tcg2Protocol, - MeasureBootProtocols.CcProtocol - )); + DEBUG ( + ( + DEBUG_INFO, + "Tcg2Protocol =3D %p, CcMeasurementProtocol =3D %p\n", + MeasureBootProtocols.Tcg2Protocol, + MeasureBootProtocols.CcProtocol + ) + ); =20 // // Copy File Device Path diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLi= bSanitization.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureB= ootLibSanitization.c new file mode 100644 index 000000000000..e2309655d384 --- /dev/null +++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSaniti= zation.c @@ -0,0 +1,275 @@ +/** @file + The library instance provides security service of TPM2 measure boot and + Confidential Computing (CC) measure boot. + + Caution: This file requires additional review when modified. + This library will have external input - PE/COFF image and GPT partition. + This external input must be validated carefully to avoid security issue = like + buffer overflow, integer overflow. + + This file will pull out the validation logic from the following function= s, in an + attempt to validate the untrusted input in the form of unit tests + + These are those functions: + + DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF ima= ge content + read is within the image buffer. + + Tcg2MeasureGptTable() function will receive untrusted GPT partition tabl= e, and parse + partition data carefully. + + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DxeTpm2MeasureBootLibSanitization.h" + +#define GPT_HEADER_REVISION_V1 0x00010000 + +/** + This function will validate the EFI_PARTITION_TABLE_HEADER structure is = safe to parse + However this function will not attempt to verify the validity of the GPT= partition + It will check the following: + - Signature + - Revision + - AlternateLBA + - FirstUsableLBA + - LastUsableLBA + - PartitionEntryLBA + - NumberOfPartitionEntries + - SizeOfPartitionEntry + - BlockIo + + @param[in] PrimaryHeader + Pointer to the EFI_PARTITION_TABLE_HEADER structure. + + @param[in] BlockIo + Pointer to the EFI_BLOCK_IO_PROTOCOL structure. + + @retval EFI_SUCCESS + The EFI_PARTITION_TABLE_HEADER structure is valid. + + @retval EFI_INVALID_PARAMETER + The EFI_PARTITION_TABLE_HEADER structure is invalid. +**/ +EFI_STATUS +EFIAPI +SanitizeEfiPartitionTableHeader ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo + ) +{ + // + // Verify that the input parameters are safe to use + // + if (PrimaryHeader =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); + return EFI_INVALID_PARAMETER; + } + + if ((BlockIo =3D=3D NULL) || (BlockIo->Media =3D=3D NULL)) { + DEBUG ((DEBUG_ERROR, "Invalid BlockIo!\n")); + return EFI_INVALID_PARAMETER; + } + + // + // The signature must be EFI_PTAB_HEADER_ID ("EFI PART" in ASCII) + // + if (PrimaryHeader->Header.Signature !=3D EFI_PTAB_HEADER_ID) { + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); + return EFI_DEVICE_ERROR; + } + + // + // The version must be GPT_HEADER_REVISION_V1 (0x00010000) + // + if (PrimaryHeader->Header.Revision !=3D GPT_HEADER_REVISION_V1) { + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header Revision!\n")); + return EFI_DEVICE_ERROR; + } + + // + // The HeaderSize must be greater than or equal to 92 and must be less t= han or equal to the logical block size + // + if ((PrimaryHeader->Header.HeaderSize < sizeof (EFI_PARTITION_TABLE_HEAD= ER)) || (PrimaryHeader->Header.HeaderSize > BlockIo->Media->BlockSize)) { + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header HeaderSize!\n")); + return EFI_DEVICE_ERROR; + } + + // + // The partition entries should all be before the first usable block + // + if (PrimaryHeader->FirstUsableLBA <=3D PrimaryHeader->PartitionEntryLBA)= { + DEBUG ((DEBUG_ERROR, "GPT PartitionEntryLBA is not less than FirstUsab= leLBA!\n")); + return EFI_DEVICE_ERROR; + } + + // + // Check that the PartitionEntryLBA greater than the Max LBA + // This will be used later for multiplication + // + if (PrimaryHeader->PartitionEntryLBA > DivU64x32 (MAX_UINT64, BlockIo->M= edia->BlockSize)) { + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header PartitionEntryLBA= !\n")); + return EFI_DEVICE_ERROR; + } + + // + // Check that the number of partition entries is greater than zero + // + if (PrimaryHeader->NumberOfPartitionEntries =3D=3D 0) { + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartition= Entries!\n")); + return EFI_DEVICE_ERROR; + } + + // + // SizeOfPartitionEntry must be 128, 256, 512... improper size may lead = to accessing uninitialized memory + // + if ((PrimaryHeader->SizeOfPartitionEntry < 128) || ((PrimaryHeader->Size= OfPartitionEntry & (PrimaryHeader->SizeOfPartitionEntry - 1)) !=3D 0)) { + DEBUG ((DEBUG_ERROR, "SizeOfPartitionEntry shall be set to a value of = 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 2= 56, 512, etc.)!\n")); + return EFI_DEVICE_ERROR; + } + + // + // This check is to prevent overflow when calculating the allocation siz= e for the partition entries + // This check will be used later for multiplication + // + if (PrimaryHeader->NumberOfPartitionEntries > DivU64x32 (MAX_UINT64, Pri= maryHeader->SizeOfPartitionEntry)) { + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartition= Entries!\n")); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + This function will validate that the allocation size from the primary he= ader is sane + It will check the following: + - AllocationSize does not overflow + + @param[in] PrimaryHeader + Pointer to the EFI_PARTITION_TABLE_HEADER structure. + + @param[out] AllocationSize + Pointer to the allocation size. + + @retval EFI_SUCCESS + The allocation size is valid. + + @retval EFI_OUT_OF_RESOURCES + The allocation size is invalid. +**/ +EFI_STATUS +EFIAPI +SanitizePrimaryHeaderAllocationSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + OUT UINT32 *AllocationSize + ) +{ + EFI_STATUS Status; + + if (PrimaryHeader =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (AllocationSize =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Replacing logic: + // PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartit= ionEntry; + // + Status =3D SafeUint32Mult (PrimaryHeader->NumberOfPartitionEntries, Prim= aryHeader->SizeOfPartitionEntry, AllocationSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Allocation Size would have overflowed!\n")); + return EFI_BAD_BUFFER_SIZE; + } + + return EFI_SUCCESS; +} + +/** + This function will validate that the Gpt Event Size calculated from the = primary header is sane + It will check the following: + - EventSize does not overflow + + Important: This function includes the entire length of the allocated spa= ce, including + (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) . When hashing the= buffer allocated with this + size, the caller must subtract the size of the (sizeof (EFI_TCG2_EVENT) = - sizeof (Tcg2Event->Event)) + from the size of the buffer before hashing. + + @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER str= ucture. + @param[in] NumberOfPartition - Number of partitions. + @param[out] EventSize - Pointer to the event size. + + @retval EFI_SUCCESS + The event size is valid. + + @retval EFI_OUT_OF_RESOURCES + Overflow would have occurred. + + @retval EFI_INVALID_PARAMETER + One of the passed parameters was invalid. +**/ +EFI_STATUS +SanitizePrimaryHeaderGptEventSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN UINTN NumberOfPartition, + OUT UINT32 *EventSize + ) +{ + EFI_STATUS Status; + UINT32 SafeNumberOfPartitions; + + if (PrimaryHeader =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (EventSize =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // We shouldn't even attempt to perform the multiplication if the number= of partitions is greater than the maximum value of UINT32 + // + Status =3D SafeUintnToUint32 (NumberOfPartition, &SafeNumberOfPartitions= ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "NumberOfPartition would have overflowed!\n")); + return EFI_INVALID_PARAMETER; + } + + // + // Replacing logic: + // (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) + Numbe= rOfPartition * PrimaryHeader.SizeOfPartitionEntry); + // + Status =3D SafeUint32Mult (SafeNumberOfPartitions, PrimaryHeader->SizeOf= PartitionEntry, EventSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Event Size would have overflowed!\n")); + return EFI_BAD_BUFFER_SIZE; + } + + // + // Replacing logic: + // *EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event); + // + Status =3D SafeUint32Add ( + OFFSET_OF (EFI_TCG2_EVENT, Event) + OFFSET_OF (EFI_GPT_DATA, = Partitions), + *EventSize, + EventSize + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Event Size would have overflowed because of GPTD= ata!\n")); + return EFI_BAD_BUFFER_SIZE; + } + + return EFI_SUCCESS; +} diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/Dxe= Tpm2MeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpm2MeasureBo= otLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c new file mode 100644 index 000000000000..3eb9763e3c91 --- /dev/null +++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2Mea= sureBootLibSanitizationTest.c @@ -0,0 +1,303 @@ +/** @file + This file includes the unit test cases for the DxeTpm2MeasureBootLibSani= tizationTest.c. + + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../DxeTpm2MeasureBootLibSanitization.h" + +#define UNIT_TEST_NAME "DxeTpm2MeasureBootLibSanitizationTest" +#define UNIT_TEST_VERSION "1.0" + +#define DEFAULT_PRIMARY_TABLE_HEADER_REVISION 0x000100= 00 +#define DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES 1 +#define DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY 128 + +/** + This function tests the SanitizeEfiPartitionTableHeader function. + It's intent is to test that a malicious EFI_PARTITION_TABLE_HEADER + structure will not cause undefined or unexpected behavior. + + In general the TPM should still be able to measure the data, but + be the header should be sanitized to prevent any unexpected behavior. + + @param[in] Context The unit test context. + + @retval UNIT_TEST_PASSED The test passed. + @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. +**/ +UNIT_TEST_STATUS +EFIAPI +TestSanitizeEfiPartitionTableHeader ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + EFI_PARTITION_TABLE_HEADER PrimaryHeader; + EFI_BLOCK_IO_PROTOCOL BlockIo; + EFI_BLOCK_IO_MEDIA BlockMedia; + + // Generate EFI_BLOCK_IO_MEDIA test data + BlockMedia.MediaId =3D 1; + BlockMedia.RemovableMedia =3D FALSE; + BlockMedia.MediaPresent =3D TRUE; + BlockMedia.LogicalPartition =3D FALSE; + BlockMedia.ReadOnly =3D FALSE; + BlockMedia.WriteCaching =3D FALSE; + BlockMedia.BlockSize =3D 512; + BlockMedia.IoAlign =3D 1; + BlockMedia.LastBlock =3D 0; + + // Generate EFI_BLOCK_IO_PROTOCOL test data + BlockIo.Revision =3D 1; + BlockIo.Media =3D &BlockMedia; + BlockIo.Reset =3D NULL; + BlockIo.ReadBlocks =3D NULL; + BlockIo.WriteBlocks =3D NULL; + BlockIo.FlushBlocks =3D NULL; + + // Geneate EFI_PARTITION_TABLE_HEADER test data + PrimaryHeader.Header.Signature =3D EFI_PTAB_HEADER_ID; + PrimaryHeader.Header.Revision =3D DEFAULT_PRIMARY_TABLE_HEADER_= REVISION; + PrimaryHeader.Header.HeaderSize =3D sizeof (EFI_PARTITION_TABLE_H= EADER); + PrimaryHeader.MyLBA =3D 1; + PrimaryHeader.AlternateLBA =3D 2; + PrimaryHeader.FirstUsableLBA =3D 3; + PrimaryHeader.LastUsableLBA =3D 4; + PrimaryHeader.PartitionEntryLBA =3D 5; + PrimaryHeader.NumberOfPartitionEntries =3D DEFAULT_PRIMARY_TABLE_HEADER_= NUMBER_OF_PARTITION_ENTRIES; + PrimaryHeader.SizeOfPartitionEntry =3D DEFAULT_PRIMARY_TABLE_HEADER_= SIZE_OF_PARTITION_ENTRY; + PrimaryHeader.PartitionEntryArrayCRC32 =3D 0; // Purposely invalid + + // Calculate the CRC32 of the PrimaryHeader + PrimaryHeader.Header.CRC32 =3D CalculateCrc32 ((UINT8 *)&PrimaryHeader, = PrimaryHeader.Header.HeaderSize); + + // Test that a normal PrimaryHeader passes validation + Status =3D SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Test that when number of partition entries is 0, the function returns= EFI_DEVICE_ERROR + // Should print "Invalid Partition Table Header NumberOfPartitionEntries= !"" + PrimaryHeader.NumberOfPartitionEntries =3D 0; + Status =3D SanitizeEfiPartitionTableHead= er (&PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + PrimaryHeader.NumberOfPartitionEntries =3D DEFAULT_PRIMARY_TABLE_HEADER_= SIZE_OF_PARTITION_ENTRY; + + // Test that when the header size is too small, the function returns EFI= _DEVICE_ERROR + // Should print "Invalid Partition Table Header Size!" + PrimaryHeader.Header.HeaderSize =3D 0; + Status =3D SanitizeEfiPartitionTableHeader (&Pr= imaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + PrimaryHeader.Header.HeaderSize =3D sizeof (EFI_PARTITION_TABLE_HEADER); + + // Test that when the SizeOfPartitionEntry is too small, the function re= turns EFI_DEVICE_ERROR + // should print: "SizeOfPartitionEntry shall be set to a value of 128 x = 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 51= 2, etc.)!" + PrimaryHeader.SizeOfPartitionEntry =3D 1; + Status =3D SanitizeEfiPartitionTableHeader (= &PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); + + return UNIT_TEST_PASSED; +} + +/** + This function tests the SanitizePrimaryHeaderAllocationSize function. + It's intent is to test that the untrusted input from a EFI_PARTITION_TAB= LE_HEADER + structure will not cause an overflow when calculating the allocation siz= e. + + @param[in] Context The unit test context. + + @retval UNIT_TEST_PASSED The test passed. + @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. +**/ +UNIT_TEST_STATUS +EFIAPI +TestSanitizePrimaryHeaderAllocationSize ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UINT32 AllocationSize; + + EFI_STATUS Status; + EFI_PARTITION_TABLE_HEADER PrimaryHeader; + + // Test that a normal PrimaryHeader passes validation + PrimaryHeader.NumberOfPartitionEntries =3D 5; + PrimaryHeader.SizeOfPartitionEntry =3D DEFAULT_PRIMARY_TABLE_HEADER_= SIZE_OF_PARTITION_ENTRY; + + Status =3D SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &Allocat= ionSize); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Test that the allocation size is correct compared to the existing log= ic + UT_ASSERT_EQUAL (AllocationSize, PrimaryHeader.NumberOfPartitionEntries = * PrimaryHeader.SizeOfPartitionEntry); + + // Test that an overflow is detected + PrimaryHeader.NumberOfPartitionEntries =3D MAX_UINT32; + PrimaryHeader.SizeOfPartitionEntry =3D 5; + Status =3D SanitizePrimaryHeaderAllocati= onSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test the inverse + PrimaryHeader.NumberOfPartitionEntries =3D 5; + PrimaryHeader.SizeOfPartitionEntry =3D MAX_UINT32; + Status =3D SanitizePrimaryHeaderAllocati= onSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test the worst case scenario + PrimaryHeader.NumberOfPartitionEntries =3D MAX_UINT32; + PrimaryHeader.SizeOfPartitionEntry =3D MAX_UINT32; + Status =3D SanitizePrimaryHeaderAllocati= onSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); + + return UNIT_TEST_PASSED; +} + +/** + This function tests the SanitizePrimaryHeaderGptEventSize function. + It's intent is to test that the untrusted input from a EFI_GPT_DATA stru= cture + will not cause an overflow when calculating the event size. + + @param[in] Context The unit test context. + + @retval UNIT_TEST_PASSED The test passed. + @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. +**/ +UNIT_TEST_STATUS +EFIAPI +TestSanitizePrimaryHeaderGptEventSize ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UINT32 EventSize; + UINT32 ExistingLogicEventSize; + EFI_STATUS Status; + EFI_PARTITION_TABLE_HEADER PrimaryHeader; + UINTN NumberOfPartition; + EFI_GPT_DATA *GptData; + EFI_TCG2_EVENT *Tcg2Event; + + Tcg2Event =3D NULL; + GptData =3D NULL; + + // Test that a normal PrimaryHeader passes validation + PrimaryHeader.NumberOfPartitionEntries =3D 5; + PrimaryHeader.SizeOfPartitionEntry =3D DEFAULT_PRIMARY_TABLE_HEADER_= SIZE_OF_PARTITION_ENTRY; + + // set the number of partitions + NumberOfPartition =3D 13; + + // that the primary event size is correct + Status =3D SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPa= rtition, &EventSize); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Calculate the existing logic event size + ExistingLogicEventSize =3D (UINT32)(OFFSET_OF (EFI_TCG2_EVENT, Event) + = OFFSET_OF (EFI_GPT_DATA, Partitions) + + NumberOfPartition * PrimaryHeader.Si= zeOfPartitionEntry); + + // Check that the event size is correct + UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize); + + // Tests that the primary event size may not overflow + Status =3D SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32= , &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test that the size of partition entries may not overflow + PrimaryHeader.SizeOfPartitionEntry =3D MAX_UINT32; + Status =3D SanitizePrimaryHeaderGptEventSize= (&PrimaryHeader, NumberOfPartition, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); + + return UNIT_TEST_PASSED; +} + +// *--------------------------------------------------------------------* +// * Unit Test Code Main Function +// *--------------------------------------------------------------------* + +/** + This function acts as the entry point for the unit tests. + + @retval UNIT_TEST_PASSED The test passed. + @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. + @retval others The test failed. +**/ +EFI_STATUS +EFIAPI +UefiTestMain ( + VOID + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE Tcg2MeasureBootLibValidationTestSuite; + + Framework =3D NULL; + + DEBUG ((DEBUG_INFO, "%a: TestMain() - Start\n", UNIT_TEST_NAME)); + + Status =3D InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCaller= BaseName, UNIT_TEST_VERSION); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed in InitUnitTestFramework. Status =3D = %r\n", UNIT_TEST_NAME, Status)); + goto EXIT; + } + + Status =3D CreateUnitTestSuite (&Tcg2MeasureBootLibValidationTestSuite, = Framework, "Tcg2MeasureBootLibValidationTestSuite", "Common.Tcg2MeasureBoot= LibValidation", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%s: Failed in CreateUnitTestSuite for Tcg2Measur= eBootLibValidationTestSuite\n", UNIT_TEST_NAME)); + Status =3D EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + // -----------Suite---------------------------------Description---------= -------------------Class----------------------------------Test Function----= --------------------Pre---Clean-Context + AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Validating EF= I Partition Table", "Common.Tcg2MeasureBootLibValidation", TestSanitizeEfiP= artitionTableHeader, NULL, NULL, NULL); + AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary heade= r gpt event checks for overflow", "Common.Tcg2MeasureBootLibValidation", Te= stSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); + AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary heade= r allocation size checks for overflow", "Common.Tcg2MeasureBootLibValidatio= n", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); + + Status =3D RunAllTestSuites (Framework); + +EXIT: + if (Framework !=3D NULL) { + FreeUnitTestFramework (Framework); + } + + DEBUG ((DEBUG_INFO, "%a: TestMain() - End\n", UNIT_TEST_NAME)); + return Status; +} + +/// +/// Avoid ECC error for function name that starts with lower case letter +/// +#define DxeTpm2MeasureBootLibUnitTestMain main + +/** + Standard POSIX C entry point for host based unit test execution. + + @param[in] Argc Number of arguments + @param[in] Argv Array of pointers to arguments + + @retval 0 Success + @retval other Error +**/ +INT32 +DxeTpm2MeasureBootLibUnitTestMain ( + IN INT32 Argc, + IN CHAR8 *Argv[] + ) +{ + return (INT32)UefiTestMain (); +} diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.y= aml index 3f03762bd6f9..24389531afaa 100644 --- a/SecurityPkg/SecurityPkg.ci.yaml +++ b/SecurityPkg/SecurityPkg.ci.yaml @@ -16,6 +16,7 @@ ## ] "ExceptionList": [ "8005", "gRT", + "8001", "DxeTpm2MeasureBootLibUnitTestMain", ], ## Both file path and directory path are accepted. "IgnoreFiles": [ --=20 2.43.0 -=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 (#113757): https://edk2.groups.io/g/devel/message/113757 Mute This Topic: https://groups.io/mt/103689720/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 Wed May 15 19:16:36 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+113758+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+113758+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1705086963; cv=none; d=zohomail.com; s=zohoarc; b=O86JNwQoTvPvTjLOneL2eLkydoxhAZIn9CxCQtm/RCpZkPkSxBpdAJlAyccJ7RoBhdnR3owg59+Hl4flLh9aZEwRUAdZ297hrGxi0QVvXWP0mik8I7o62ONhfU08EwO4tu9OJ0wx/CEqBW5QjEpaBGOAwUozoWbhiNYgbe/8AR8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1705086963; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=9OS4Mh1Smr+5FjE77iCGEHO2WupVNgKZ0DyJsxyI6o4=; b=eA8xjoeIhDizdwey3XRUEQOLts1G3XXMSeyHUdWaocVe3Mv8DvU/VC543pFZrsWhCkt77mA79S81ySzxx0IMLsDwkWFCuOh/dRJXNGWQ3Qrz85elC2Sg5dfoU/ZvH/oEzDyWZsaHmR2uy6A6Yp0z61qU0q/01qDI9EYU/Fy7Erg= 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+113758+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1705086963778997.3111709832468; Fri, 12 Jan 2024 11:16:03 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=zKYiRqzb36xgJTSml6gVp3N67efGrflkoTy1n3bmQUM=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1705086963; v=1; b=vDqeqFwSikJ+W/moODFIuu+PPM9xenIf40nsaDMogIb4i85tzYWpAPT75hPIaL0pD4cOxFcg ezRy+9zOk1+S9+Tv65uTlXTZ8Wn9VvvdkpdfoC2YxCXiHtKtDQj5i7jtfU68F5wL1UTU+uY25tp eilqz2QUxydth7EHVdEaKV+w= X-Received: by 127.0.0.2 with SMTP id 5HkCYY1788612xxcAjZNtbPr; Fri, 12 Jan 2024 11:16:03 -0800 X-Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) by mx.groups.io with SMTP id smtpd.web10.18728.1704997015938433705 for ; Thu, 11 Jan 2024 10:16:56 -0800 X-Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-1d4ab4e65aeso42713925ad.0 for ; Thu, 11 Jan 2024 10:16:55 -0800 (PST) X-Gm-Message-State: lVy1N8h2nIcBiCicIqNOzjfOx1787277AA= X-Google-Smtp-Source: AGHT+IEE2h8mjgi9TcGmJG+IGWnZsr3PxpUlGobNFQk4x799IwoC+EY0sxqG4hIvlVyvQUpMLygQJw== X-Received: by 2002:a17:902:ff01:b0:1d4:40f3:7ab9 with SMTP id f1-20020a170902ff0100b001d440f37ab9mr1644549plj.40.1704997014275; Thu, 11 Jan 2024 10:16:54 -0800 (PST) X-Received: from localhost.localdomain ([131.107.1.208]) by smtp.gmail.com with ESMTPSA id kd13-20020a17090313cd00b001d4752f5403sm1453414plb.206.2024.01.11.10.16.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Jan 2024 10:16:53 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: "Douglas Flick [MSFT]" , Jiewen Yao Subject: [edk2-devel] [PATCH 2/6] SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4117 - CVE 2022-36763 Date: Thu, 11 Jan 2024 10:16:02 -0800 Message-ID: <3e347894f931240d0a7d5a74b0cc381ea0b29b15.1704996627.git.doug.edk2@gmail.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: 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,dougflick@microsoft.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1705086964269100005 Content-Type: text/plain; charset="utf-8" This commit contains the patch files and tests for DxeTpmMeasureBootLib CVE 2022-36763. Cc: Jiewen Yao Signed-off-by: Doug Flick [MSFT] --- SecurityPkg/Test/SecurityPkgHostTest.dsc | 1 + .../DxeTpmMeasureBootLib.inf | 4 +- ...eTpmMeasureBootLibSanitizationTestHost.inf | 28 ++ .../DxeTpmMeasureBootLibSanitization.h | 114 +++++++ .../DxeTpmMeasureBootLib.c | 40 ++- .../DxeTpmMeasureBootLibSanitization.c | 241 ++++++++++++++ .../DxeTpmMeasureBootLibSanitizationTest.c | 301 ++++++++++++++++++ SecurityPkg/SecurityPkg.ci.yaml | 1 + 8 files changed, 716 insertions(+), 14 deletions(-) create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTe= st/DxeTpmMeasureBootLibSanitizationTestHost.inf create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureB= ootLibSanitization.h create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureB= ootLibSanitization.c create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTe= st/DxeTpmMeasureBootLibSanitizationTest.c diff --git a/SecurityPkg/Test/SecurityPkgHostTest.dsc b/SecurityPkg/Test/Se= curityPkgHostTest.dsc index 788c1ab6fec6..1655e573eae4 100644 --- a/SecurityPkg/Test/SecurityPkgHostTest.dsc +++ b/SecurityPkg/Test/SecurityPkgHostTest.dsc @@ -27,6 +27,7 @@ [Components] SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/Moc= kPlatformPKProtectionLib.inf SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2Measur= eBootLibSanitizationTestHost.inf + SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureB= ootLibSanitizationTestHost.inf =20 # # Build SecurityPkg HOST_APPLICATION Tests diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.= inf b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf index ebab6f7c1e1e..414c654d156a 100644 --- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf +++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf @@ -32,6 +32,8 @@ [Defines] =20 [Sources] DxeTpmMeasureBootLib.c + DxeTpmMeasureBootLibSanitization.c + DxeTpmMeasureBootLibSanitization.h =20 [Packages] MdePkg/MdePkg.dec @@ -41,6 +43,7 @@ [Packages] =20 [LibraryClasses] BaseMemoryLib + SafeIntLib DebugLib MemoryAllocationLib DevicePathLib @@ -59,4 +62,3 @@ [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES - diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeT= pmMeasureBootLibSanitizationTestHost.inf b/SecurityPkg/Library/DxeTpmMeasur= eBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf new file mode 100644 index 000000000000..47b0811b00bc --- /dev/null +++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasu= reBootLibSanitizationTestHost.inf @@ -0,0 +1,28 @@ +## @file +# This file builds the unit tests for DxeTpmMeasureBootLib +# +# Copyright (C) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x00010006 + BASE_NAME =3D DxeTpmMeasuredBootLibTest + FILE_GUID =3D eb01bc38-309c-4d3e-967e-9f078c90772f + MODULE_TYPE =3D HOST_APPLICATION + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D main + +[Sources] + DxeTpmMeasureBootLibSanitizationTest.c + ../DxeTpmMeasureBootLibSanitization.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + UnitTestLib + PrintLib + SafeIntLib diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibS= anitization.h b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootL= ibSanitization.h new file mode 100644 index 000000000000..0d9d00c281f6 --- /dev/null +++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitiza= tion.h @@ -0,0 +1,114 @@ +/** @file + This file includes the function prototypes for the sanitization function= s. + + These are those functions: + + DxeTpmMeasureBootLibImageRead() function will make sure the PE/COFF imag= e content + read is within the image buffer. + + TcgMeasurePeImage() function will accept untrusted PE/COFF image and val= idate its + data structure within this image buffer before use. + + TcgMeasureGptTable() function will receive untrusted GPT partition table= , and parse + partition data carefully. + + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ +#define DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ + +#include +#include +#include +#include + +/** + This function will validate the EFI_PARTITION_TABLE_HEADER structure is = safe to parse + However this function will not attempt to verify the validity of the GPT= partition + It will check the following: + - Signature + - Revision + - AlternateLBA + - FirstUsableLBA + - LastUsableLBA + - PartitionEntryLBA + - NumberOfPartitionEntries + - SizeOfPartitionEntry + - BlockIo + + @param[in] PrimaryHeader + Pointer to the EFI_PARTITION_TABLE_HEADER structure. + + @param[in] BlockIo + Pointer to the EFI_BLOCK_IO_PROTOCOL structure. + + @retval EFI_SUCCESS + The EFI_PARTITION_TABLE_HEADER structure is valid. + + @retval EFI_INVALID_PARAMETER + The EFI_PARTITION_TABLE_HEADER structure is invalid. +**/ +EFI_STATUS +EFIAPI +SanitizeEfiPartitionTableHeader ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo + ); + +/** + This function will validate that the allocation size from the primary he= ader is sane + It will check the following: + - AllocationSize does not overflow + + @param[in] PrimaryHeader + Pointer to the EFI_PARTITION_TABLE_HEADER structure. + + @param[out] AllocationSize + Pointer to the allocation size. + + @retval EFI_SUCCESS + The allocation size is valid. + + @retval EFI_OUT_OF_RESOURCES + The allocation size is invalid. +**/ +EFI_STATUS +EFIAPI +SanitizePrimaryHeaderAllocationSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + OUT UINT32 *AllocationSize + ); + +/** + This function will validate that the Gpt Event Size calculated from the = primary header is sane + It will check the following: + - EventSize does not overflow + + Important: This function includes the entire length of the allocated spa= ce, including the + TCG_PCR_EVENT_HDR. When hashing the buffer allocated with this size, the= caller must subtract + the size of the TCG_PCR_EVENT_HDR from the size of the buffer before has= hing. + + @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER str= ucture. + @param[in] NumberOfPartition - Number of partitions. + @param[out] EventSize - Pointer to the event size. + + @retval EFI_SUCCESS + The event size is valid. + + @retval EFI_OUT_OF_RESOURCES + Overflow would have occurred. + + @retval EFI_INVALID_PARAMETER + One of the passed parameters was invalid. +**/ +EFI_STATUS +SanitizePrimaryHeaderGptEventSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN UINTN NumberOfPartition, + OUT UINT32 *EventSize + ); + +#endif // DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.= c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c index 220393dd2beb..669ab1913440 100644 --- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c @@ -18,6 +18,8 @@ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 +Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ =20 #include @@ -40,6 +42,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include =20 +#include "DxeTpmMeasureBootLibSanitization.h" + // // Flag to check GPT partition. It only need be measured once. // @@ -136,6 +140,9 @@ TcgMeasureGptTable ( UINT32 EventSize; UINT32 EventNumber; EFI_PHYSICAL_ADDRESS EventLogLastEntry; + UINT32 AllocSize; + + GptData =3D NULL; =20 if (mMeasureGptCount > 0) { return EFI_SUCCESS; @@ -166,8 +173,8 @@ TcgMeasureGptTable ( BlockIo->Media->BlockSize, (UINT8 *)PrimaryHeader ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed to Read Partition Table Header!\n")); + if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (Pr= imaryHeader, BlockIo))) { + DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid= Partition Table Header!\n")); FreePool (PrimaryHeader); return EFI_DEVICE_ERROR; } @@ -175,7 +182,13 @@ TcgMeasureGptTable ( // // Read the partition entry. // - EntryPtr =3D (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntr= ies * PrimaryHeader->SizeOfPartitionEntry); + Status =3D SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSiz= e); + if (EFI_ERROR (Status)) { + FreePool (PrimaryHeader); + return EFI_DEVICE_ERROR; + } + + EntryPtr =3D (UINT8 *)AllocatePool (AllocSize); if (EntryPtr =3D=3D NULL) { FreePool (PrimaryHeader); return EFI_OUT_OF_RESOURCES; @@ -185,7 +198,7 @@ TcgMeasureGptTable ( DiskIo, BlockIo->Media->MediaId, MultU64x32 (PrimaryHeader->PartitionEntryLBA, BlockIo= ->Media->BlockSize), - PrimaryHeader->NumberOfPartitionEntries * PrimaryHead= er->SizeOfPartitionEntry, + AllocSize, EntryPtr ); if (EFI_ERROR (Status)) { @@ -210,9 +223,8 @@ TcgMeasureGptTable ( // // Prepare Data for Measurement // - EventSize =3D (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitio= ns) - + NumberOfPartition * PrimaryHeader->SizeOfPartitio= nEntry); - TcgEvent =3D (TCG_PCR_EVENT *)AllocateZeroPool (EventSize + sizeof (TCG_= PCR_EVENT_HDR)); + Status =3D SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfP= artition, &EventSize); + TcgEvent =3D (TCG_PCR_EVENT *)AllocateZeroPool (EventSize); if (TcgEvent =3D=3D NULL) { FreePool (PrimaryHeader); FreePool (EntryPtr); @@ -221,7 +233,7 @@ TcgMeasureGptTable ( =20 TcgEvent->PCRIndex =3D 5; TcgEvent->EventType =3D EV_EFI_GPT_EVENT; - TcgEvent->EventSize =3D EventSize; + TcgEvent->EventSize =3D EventSize - sizeof (TCG_PCR_EVENT_HDR); GptData =3D (EFI_GPT_DATA *)TcgEvent->Event; =20 // @@ -361,11 +373,13 @@ TcgMeasurePeImage ( TcgEvent->PCRIndex =3D 2; break; default: - DEBUG (( - DEBUG_ERROR, - "TcgMeasurePeImage: Unknown subsystem type %d", - ImageType - )); + DEBUG ( + ( + DEBUG_ERROR, + "TcgMeasurePeImage: Unknown subsystem type %d", + ImageType + ) + ); goto Finish; } =20 diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibS= anitization.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootL= ibSanitization.c new file mode 100644 index 000000000000..a3fa46f5e632 --- /dev/null +++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitiza= tion.c @@ -0,0 +1,241 @@ +/** @file + The library instance provides security service of TPM2 measure boot and + Confidential Computing (CC) measure boot. + + Caution: This file requires additional review when modified. + This library will have external input - PE/COFF image and GPT partition. + This external input must be validated carefully to avoid security issue = like + buffer overflow, integer overflow. + + This file will pull out the validation logic from the following function= s, in an + attempt to validate the untrusted input in the form of unit tests + + These are those functions: + + DxeTpmMeasureBootLibImageRead() function will make sure the PE/COFF imag= e content + read is within the image buffer. + + Tcg2MeasureGptTable() function will receive untrusted GPT partition tabl= e, and parse + partition data carefully. + + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DxeTpmMeasureBootLibSanitization.h" + +#define GPT_HEADER_REVISION_V1 0x00010000 + +/** + This function will validate the EFI_PARTITION_TABLE_HEADER structure is = safe to parse + However this function will not attempt to verify the validity of the GPT= partition + It will check the following: + - Signature + - Revision + - AlternateLBA + - FirstUsableLBA + - LastUsableLBA + - PartitionEntryLBA + - NumberOfPartitionEntries + - SizeOfPartitionEntry + - BlockIo + + @param[in] PrimaryHeader + Pointer to the EFI_PARTITION_TABLE_HEADER structure. + + @param[in] BlockIo + Pointer to the EFI_BLOCK_IO_PROTOCOL structure. + + @retval EFI_SUCCESS + The EFI_PARTITION_TABLE_HEADER structure is valid. + + @retval EFI_INVALID_PARAMETER + The EFI_PARTITION_TABLE_HEADER structure is invalid. +**/ +EFI_STATUS +EFIAPI +SanitizeEfiPartitionTableHeader ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo + ) +{ + // Verify that the input parameters are safe to use + if (PrimaryHeader =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); + return EFI_INVALID_PARAMETER; + } + + if ((BlockIo =3D=3D NULL) || (BlockIo->Media =3D=3D NULL)) { + DEBUG ((DEBUG_ERROR, "Invalid BlockIo!\n")); + return EFI_INVALID_PARAMETER; + } + + // The signature must be EFI_PTAB_HEADER_ID ("EFI PART" in ASCII) + if (PrimaryHeader->Header.Signature !=3D EFI_PTAB_HEADER_ID) { + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n")); + return EFI_DEVICE_ERROR; + } + + // The version must be GPT_HEADER_REVISION_V1 (0x00010000) + if (PrimaryHeader->Header.Revision !=3D GPT_HEADER_REVISION_V1) { + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header Revision!\n")); + return EFI_DEVICE_ERROR; + } + + // The HeaderSize must be greater than or equal to 92 and must be less t= han or equal to the logical block size + if ((PrimaryHeader->Header.HeaderSize < sizeof (EFI_PARTITION_TABLE_HEAD= ER)) || (PrimaryHeader->Header.HeaderSize > BlockIo->Media->BlockSize)) { + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header HeaderSize!\n")); + return EFI_DEVICE_ERROR; + } + + // check that the PartitionEntryLBA greater than the Max LBA + // This will be used later for multiplication + if (PrimaryHeader->PartitionEntryLBA > DivU64x32 (MAX_UINT64, BlockIo->M= edia->BlockSize)) { + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header PartitionEntryLBA= !\n")); + return EFI_DEVICE_ERROR; + } + + // Check that the number of partition entries is greater than zero + if (PrimaryHeader->NumberOfPartitionEntries =3D=3D 0) { + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartition= Entries!\n")); + return EFI_DEVICE_ERROR; + } + + // SizeOfPartitionEntry must be 128, 256, 512... improper size may lead = to accessing uninitialized memory + if ((PrimaryHeader->SizeOfPartitionEntry < 128) || ((PrimaryHeader->Size= OfPartitionEntry & (PrimaryHeader->SizeOfPartitionEntry - 1)) !=3D 0)) { + DEBUG ((DEBUG_ERROR, "SizeOfPartitionEntry shall be set to a value of = 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 2= 56, 512, etc.)!\n")); + return EFI_DEVICE_ERROR; + } + + // This check is to prevent overflow when calculating the allocation siz= e for the partition entries + // This check will be used later for multiplication + if (PrimaryHeader->NumberOfPartitionEntries > DivU64x32 (MAX_UINT64, Pri= maryHeader->SizeOfPartitionEntry)) { + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartition= Entries!\n")); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + This function will validate that the allocation size from the primary he= ader is sane + It will check the following: + - AllocationSize does not overflow + + @param[in] PrimaryHeader + Pointer to the EFI_PARTITION_TABLE_HEADER structure. + + @param[out] AllocationSize + Pointer to the allocation size. + + @retval EFI_SUCCESS + The allocation size is valid. + + @retval EFI_OUT_OF_RESOURCES + The allocation size is invalid. +**/ +EFI_STATUS +EFIAPI +SanitizePrimaryHeaderAllocationSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + OUT UINT32 *AllocationSize + ) +{ + EFI_STATUS Status; + + if (PrimaryHeader =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (AllocationSize =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // Replacing logic: + // PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartit= ionEntry; + Status =3D SafeUint32Mult (PrimaryHeader->NumberOfPartitionEntries, Prim= aryHeader->SizeOfPartitionEntry, AllocationSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Allocation Size would have overflowed!\n")); + return EFI_BAD_BUFFER_SIZE; + } + + return EFI_SUCCESS; +} + +/** + This function will validate that the Gpt Event Size calculated from the = primary header is sane + It will check the following: + - EventSize does not overflow + + Important: This function includes the entire length of the allocated spa= ce, including the + TCG_PCR_EVENT_HDR. When hashing the buffer allocated with this size, the= caller must subtract + the size of the TCG_PCR_EVENT_HDR from the size of the buffer before has= hing. + + @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER str= ucture. + @param[in] NumberOfPartition - Number of partitions. + @param[out] EventSize - Pointer to the event size. + + @retval EFI_SUCCESS + The event size is valid. + + @retval EFI_OUT_OF_RESOURCES + Overflow would have occurred. + + @retval EFI_INVALID_PARAMETER + One of the passed parameters was invalid. +**/ +EFI_STATUS +SanitizePrimaryHeaderGptEventSize ( + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, + IN UINTN NumberOfPartition, + OUT UINT32 *EventSize + ) +{ + EFI_STATUS Status; + UINT32 SafeNumberOfPartitions; + + if (PrimaryHeader =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (EventSize =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // We shouldn't even attempt to perform the multiplication if the number= of partitions is greater than the maximum value of UINT32 + Status =3D SafeUintnToUint32 (NumberOfPartition, &SafeNumberOfPartitions= ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "NumberOfPartition would have overflowed!\n")); + return EFI_INVALID_PARAMETER; + } + + // Replacing logic: + // (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) + Numbe= rOfPartition * PrimaryHeader.SizeOfPartitionEntry + sizeof (TCG_PCR_EVENT_H= DR)); + Status =3D SafeUint32Mult (SafeNumberOfPartitions, PrimaryHeader->SizeOf= PartitionEntry, EventSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Event Size would have overflowed!\n")); + return EFI_BAD_BUFFER_SIZE; + } + + Status =3D SafeUint32Add ( + sizeof (TCG_PCR_EVENT_HDR) + + OFFSET_OF (EFI_GPT_DATA, Partitions), + *EventSize, + EventSize + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Event Size would have overflowed because of GPTD= ata!\n")); + return EFI_BAD_BUFFER_SIZE; + } + + return EFI_SUCCESS; +} diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeT= pmMeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpmMeasureBootL= ib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c new file mode 100644 index 000000000000..eeb928cdb0aa --- /dev/null +++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasu= reBootLibSanitizationTest.c @@ -0,0 +1,301 @@ +/** @file +This file includes the unit test cases for the DxeTpmMeasureBootLibSanitiz= ationTest.c. + +Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../DxeTpmMeasureBootLibSanitization.h" + +#define UNIT_TEST_NAME "DxeTpmMeasureBootLibSanitizationTest" +#define UNIT_TEST_VERSION "1.0" + +#define DEFAULT_PRIMARY_TABLE_HEADER_REVISION 0x000100= 00 +#define DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES 1 +#define DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY 128 + +/** + This function tests the SanitizeEfiPartitionTableHeader function. + It's intent is to test that a malicious EFI_PARTITION_TABLE_HEADER + structure will not cause undefined or unexpected behavior. + + In general the TPM should still be able to measure the data, but + be the header should be sanitized to prevent any unexpected behavior. + + @param[in] Context The unit test context. + + @retval UNIT_TEST_PASSED The test passed. + @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. +**/ +UNIT_TEST_STATUS +EFIAPI +TestSanitizeEfiPartitionTableHeader ( + IN UNIT_TEST_CONTEXT Context + ) +{ + EFI_STATUS Status; + EFI_PARTITION_TABLE_HEADER PrimaryHeader; + EFI_BLOCK_IO_PROTOCOL BlockIo; + EFI_BLOCK_IO_MEDIA BlockMedia; + + // Generate EFI_BLOCK_IO_MEDIA test data + BlockMedia.MediaId =3D 1; + BlockMedia.RemovableMedia =3D FALSE; + BlockMedia.MediaPresent =3D TRUE; + BlockMedia.LogicalPartition =3D FALSE; + BlockMedia.ReadOnly =3D FALSE; + BlockMedia.WriteCaching =3D FALSE; + BlockMedia.BlockSize =3D 512; + BlockMedia.IoAlign =3D 1; + BlockMedia.LastBlock =3D 0; + + // Generate EFI_BLOCK_IO_PROTOCOL test data + BlockIo.Revision =3D 1; + BlockIo.Media =3D &BlockMedia; + BlockIo.Reset =3D NULL; + BlockIo.ReadBlocks =3D NULL; + BlockIo.WriteBlocks =3D NULL; + BlockIo.FlushBlocks =3D NULL; + + // Geneate EFI_PARTITION_TABLE_HEADER test data + PrimaryHeader.Header.Signature =3D EFI_PTAB_HEADER_ID; + PrimaryHeader.Header.Revision =3D DEFAULT_PRIMARY_TABLE_HEADER_= REVISION; + PrimaryHeader.Header.HeaderSize =3D sizeof (EFI_PARTITION_TABLE_H= EADER); + PrimaryHeader.MyLBA =3D 1; + PrimaryHeader.AlternateLBA =3D 2; + PrimaryHeader.FirstUsableLBA =3D 3; + PrimaryHeader.LastUsableLBA =3D 4; + PrimaryHeader.PartitionEntryLBA =3D 5; + PrimaryHeader.NumberOfPartitionEntries =3D DEFAULT_PRIMARY_TABLE_HEADER_= NUMBER_OF_PARTITION_ENTRIES; + PrimaryHeader.SizeOfPartitionEntry =3D DEFAULT_PRIMARY_TABLE_HEADER_= SIZE_OF_PARTITION_ENTRY; + PrimaryHeader.PartitionEntryArrayCRC32 =3D 0; // Purposely invalid + + // Calculate the CRC32 of the PrimaryHeader + PrimaryHeader.Header.CRC32 =3D CalculateCrc32 ((UINT8 *)&PrimaryHeader, = PrimaryHeader.Header.HeaderSize); + + // Test that a normal PrimaryHeader passes validation + Status =3D SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Test that when number of partition entries is 0, the function returns= EFI_DEVICE_ERROR + // Should print "Invalid Partition Table Header NumberOfPartitionEntries= !"" + PrimaryHeader.NumberOfPartitionEntries =3D 0; + Status =3D SanitizeEfiPartitionTableHead= er (&PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + PrimaryHeader.NumberOfPartitionEntries =3D DEFAULT_PRIMARY_TABLE_HEADER_= SIZE_OF_PARTITION_ENTRY; + + // Test that when the header size is too small, the function returns EFI= _DEVICE_ERROR + // Should print "Invalid Partition Table Header Size!" + PrimaryHeader.Header.HeaderSize =3D 0; + Status =3D SanitizeEfiPartitionTableHeader (&Pr= imaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + PrimaryHeader.Header.HeaderSize =3D sizeof (EFI_PARTITION_TABLE_HEADER); + + // Test that when the SizeOfPartitionEntry is too small, the function re= turns EFI_DEVICE_ERROR + // should print: "SizeOfPartitionEntry shall be set to a value of 128 x = 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 51= 2, etc.)!" + PrimaryHeader.SizeOfPartitionEntry =3D 1; + Status =3D SanitizeEfiPartitionTableHeader (= &PrimaryHeader, &BlockIo); + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); + + return UNIT_TEST_PASSED; +} + +/** + This function tests the SanitizePrimaryHeaderAllocationSize function. + It's intent is to test that the untrusted input from a EFI_PARTITION_TAB= LE_HEADER + structure will not cause an overflow when calculating the allocation siz= e. + + @param[in] Context The unit test context. + + @retval UNIT_TEST_PASSED The test passed. + @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. +**/ +UNIT_TEST_STATUS +EFIAPI +TestSanitizePrimaryHeaderAllocationSize ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UINT32 AllocationSize; + + EFI_STATUS Status; + EFI_PARTITION_TABLE_HEADER PrimaryHeader; + + // Test that a normal PrimaryHeader passes validation + PrimaryHeader.NumberOfPartitionEntries =3D 5; + PrimaryHeader.SizeOfPartitionEntry =3D DEFAULT_PRIMARY_TABLE_HEADER_= SIZE_OF_PARTITION_ENTRY; + + Status =3D SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &Allocat= ionSize); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Test that the allocation size is correct compared to the existing log= ic + UT_ASSERT_EQUAL (AllocationSize, PrimaryHeader.NumberOfPartitionEntries = * PrimaryHeader.SizeOfPartitionEntry); + + // Test that an overflow is detected + PrimaryHeader.NumberOfPartitionEntries =3D MAX_UINT32; + PrimaryHeader.SizeOfPartitionEntry =3D 5; + Status =3D SanitizePrimaryHeaderAllocati= onSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test the inverse + PrimaryHeader.NumberOfPartitionEntries =3D 5; + PrimaryHeader.SizeOfPartitionEntry =3D MAX_UINT32; + Status =3D SanitizePrimaryHeaderAllocati= onSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test the worst case scenario + PrimaryHeader.NumberOfPartitionEntries =3D MAX_UINT32; + PrimaryHeader.SizeOfPartitionEntry =3D MAX_UINT32; + Status =3D SanitizePrimaryHeaderAllocati= onSize (&PrimaryHeader, &AllocationSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); + + return UNIT_TEST_PASSED; +} + +/** + This function tests the SanitizePrimaryHeaderGptEventSize function. + It's intent is to test that the untrusted input from a EFI_GPT_DATA stru= cture + will not cause an overflow when calculating the event size. + + @param[in] Context The unit test context. + + @retval UNIT_TEST_PASSED The test passed. + @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. +**/ +UNIT_TEST_STATUS +EFIAPI +TestSanitizePrimaryHeaderGptEventSize ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UINT32 EventSize; + UINT32 ExistingLogicEventSize; + EFI_STATUS Status; + EFI_PARTITION_TABLE_HEADER PrimaryHeader; + UINTN NumberOfPartition; + EFI_GPT_DATA *GptData; + + GptData =3D NULL; + + // Test that a normal PrimaryHeader passes validation + PrimaryHeader.NumberOfPartitionEntries =3D 5; + PrimaryHeader.SizeOfPartitionEntry =3D DEFAULT_PRIMARY_TABLE_HEADER_= SIZE_OF_PARTITION_ENTRY; + + // set the number of partitions + NumberOfPartition =3D 13; + + // that the primary event size is correct + Status =3D SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPa= rtition, &EventSize); + UT_ASSERT_NOT_EFI_ERROR (Status); + + // Calculate the existing logic event size + ExistingLogicEventSize =3D (UINT32)(sizeof (TCG_PCR_EVENT_HDR) + OFFSET_= OF (EFI_GPT_DATA, Partitions) + + NumberOfPartition * PrimaryHeader.Si= zeOfPartitionEntry); + + // Check that the event size is correct + UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize); + + // Tests that the primary event size may not overflow + Status =3D SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32= , &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + // Test that the size of partition entries may not overflow + PrimaryHeader.SizeOfPartitionEntry =3D MAX_UINT32; + Status =3D SanitizePrimaryHeaderGptEventSize= (&PrimaryHeader, NumberOfPartition, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); + + return UNIT_TEST_PASSED; +} + +// *--------------------------------------------------------------------* +// * Unit Test Code Main Function +// *--------------------------------------------------------------------* + +/** + This function acts as the entry point for the unit tests. + + @param argc - The number of command line arguments + @param argv - The command line arguments + + @return int - The status of the test +**/ +EFI_STATUS +EFIAPI +UefiTestMain ( + VOID + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE Framework; + UNIT_TEST_SUITE_HANDLE TcgMeasureBootLibValidationTestSuite; + + Framework =3D NULL; + + DEBUG ((DEBUG_INFO, "%a: TestMain() - Start\n", UNIT_TEST_NAME)); + + Status =3D InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCaller= BaseName, UNIT_TEST_VERSION); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed in InitUnitTestFramework. Status =3D = %r\n", UNIT_TEST_NAME, Status)); + goto EXIT; + } + + Status =3D CreateUnitTestSuite (&TcgMeasureBootLibValidationTestSuite, F= ramework, "TcgMeasureBootLibValidationTestSuite", "Common.TcgMeasureBootLib= Validation", NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%s: Failed in CreateUnitTestSuite for TcgMeasure= BootLibValidationTestSuite\n", UNIT_TEST_NAME)); + Status =3D EFI_OUT_OF_RESOURCES; + goto EXIT; + } + + // -----------Suite---------------------------------Description---------= -------------------Class----------------------------------Test Function----= --------------------Pre---Clean-Context + AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Validating EFI= Partition Table", "Common.TcgMeasureBootLibValidation", TestSanitizeEfiPar= titionTableHeader, NULL, NULL, NULL); + AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header= gpt event checks for overflow", "Common.TcgMeasureBootLibValidation", Test= SanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); + AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header= allocation size checks for overflow", "Common.TcgMeasureBootLibValidation"= , TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); + + Status =3D RunAllTestSuites (Framework); + +EXIT: + if (Framework !=3D NULL) { + FreeUnitTestFramework (Framework); + } + + DEBUG ((DEBUG_INFO, "%a: TestMain() - End\n", UNIT_TEST_NAME)); + return Status; +} + +/// +/// Avoid ECC error for function name that starts with lower case letter +/// +#define DxeTpmMeasureBootLibUnitTestMain main + +/** + Standard POSIX C entry point for host based unit test execution. + + @param[in] Argc Number of arguments + @param[in] Argv Array of pointers to arguments + + @retval 0 Success + @retval other Error +**/ +INT32 +DxeTpmMeasureBootLibUnitTestMain ( + IN INT32 Argc, + IN CHAR8 *Argv[] + ) +{ + return (INT32)UefiTestMain (); +} diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.y= aml index 24389531afaa..53e5b1fd8e69 100644 --- a/SecurityPkg/SecurityPkg.ci.yaml +++ b/SecurityPkg/SecurityPkg.ci.yaml @@ -17,6 +17,7 @@ "ExceptionList": [ "8005", "gRT", "8001", "DxeTpm2MeasureBootLibUnitTestMain", + "8001", "DxeTpmMeasureBootLibUnitTestMain" ], ## Both file path and directory path are accepted. "IgnoreFiles": [ --=20 2.43.0 -=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 (#113758): https://edk2.groups.io/g/devel/message/113758 Mute This Topic: https://groups.io/mt/103689721/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 Wed May 15 19:16:36 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+113759+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+113759+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1705086964; cv=none; d=zohomail.com; s=zohoarc; b=iBZ9LJ+KxQNSdt9Ex8jFjbat7gv4wsFIGhgENsczg+EcUisG/0IdxjgMSlCGkiJ7qWj1vs7mrtsIJ/EPQmPKUqk2euliPhFkR4UtZILmFYOU6CCBcoThxstvPwGQmwRC4Qj0ODvMMr6NACuNhQFSSTbMc7Dyog/GaPobgARBqqM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1705086964; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=cxHcEcs1YoFkk/xkaX7icfdPombBne5IUP20PKbmaks=; b=JYoHqsi6SBP5fgNIrmtzL8YCsi0EsBLAilzPkvvvht+3R0fB2y7kDv3lK0vNR/URvmLYTjtkB9in486m4Z4IZJWE+NZnDCFtIJg6OYKj9O7caTZoVAIetty0V5f3dG+MykUnRuVXBdwN65obsLbvnX8VhxMqsEB6/tsf9eh+vi8= 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+113759+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1705086964036399.72737153138246; Fri, 12 Jan 2024 11:16:04 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=QS7y3KfhcXKYPth+N+ptCcRd9SA2OHqJAXReR0iYQ/8=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1705086963; v=1; b=C3EQCSmoYelTSjd6yw7qsh+keM0/dyP3L97pY77MCfXVEHinigBJj3tlHggu9Z6lZEMRK75k a/wV/QgRcYvGASmH33McwYedXYoZnrct4Foc7pAxsxFt4dzc+lVSygmEszwvlL9PihrtqqmN8Ey fLC5qPl9E4D8cUzbS8m6Armk= X-Received: by 127.0.0.2 with SMTP id yLTSYY1788612xbIBeY4M7Zk; Fri, 12 Jan 2024 11:16:03 -0800 X-Received: from mail-pl1-f172.google.com (mail-pl1-f172.google.com [209.85.214.172]) by mx.groups.io with SMTP id smtpd.web10.18729.1704997016969417732 for ; Thu, 11 Jan 2024 10:16:57 -0800 X-Received: by mail-pl1-f172.google.com with SMTP id d9443c01a7336-1d3e8a51e6bso44965375ad.3 for ; Thu, 11 Jan 2024 10:16:56 -0800 (PST) X-Gm-Message-State: ilG6mTULd2eWnPRYN8NMmW90x1787277AA= X-Google-Smtp-Source: AGHT+IEoTQOBAFNVGBelPPJoKY1WA0xdbJFmcinFSb1PEbafZTM20dd/jCs6JEbTQMuQUSpdGsF7dQ== X-Received: by 2002:a17:902:dac5:b0:1d3:9060:62a7 with SMTP id q5-20020a170902dac500b001d3906062a7mr176829plx.35.1704997016094; Thu, 11 Jan 2024 10:16:56 -0800 (PST) X-Received: from localhost.localdomain ([131.107.1.208]) by smtp.gmail.com with ESMTPSA id kd13-20020a17090313cd00b001d4752f5403sm1453414plb.206.2024.01.11.10.16.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Jan 2024 10:16:55 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: "Douglas Flick [MSFT]" , Jiewen Yao Subject: [edk2-devel] [PATCH 3/6] SecurityPkg: : Adding CVE 2022-36763 to SecurityFixes.yaml Date: Thu, 11 Jan 2024 10:16:03 -0800 Message-ID: <4ea9896fbdef6d2cc7a443ddba9ee1d671af8bf6.1704996627.git.doug.edk2@gmail.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: 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,dougflick@microsoft.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1705086966141100018 Content-Type: text/plain; charset="utf-8" This creates / adds a security file that tracks the security fixes found in this package and can be used to find the fixes that were applied. Cc: Jiewen Yao Signed-off-by: Doug Flick [MSFT] --- SecurityPkg/SecurityFixes.yaml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 SecurityPkg/SecurityFixes.yaml diff --git a/SecurityPkg/SecurityFixes.yaml b/SecurityPkg/SecurityFixes.yaml new file mode 100644 index 000000000000..f9e3e7be7453 --- /dev/null +++ b/SecurityPkg/SecurityFixes.yaml @@ -0,0 +1,22 @@ +## @file +# Security Fixes for SecurityPkg +# +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +CVE_2022_36763: + commit_titles: + - "SecurityPkg: DxeTpm2Measurement: SECURITY PATCH 4117 - CVE 2022-367= 63" + - "SecurityPkg: DxeTpmMeasurement: SECURITY PATCH 4117 - CVE 2022-3676= 3" + - "SecurityPkg: : Adding CVE 2022-36763 to SecurityFixes.yaml" + cve: CVE-2022-36763 + date_reported: 2022-10-25 11:31 UTC + description: (CVE-2022-36763) - Heap Buffer Overflow in Tcg2MeasureGptTa= ble() + note: This patch is related to and supersedes TCBZ2168 + files_impacted: + - Library\DxeTpm2MeasureBootLib\DxeTpm2MeasureBootLib.c + - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c + links: + - https://bugzilla.tianocore.org/show_bug.cgi?id=3D4117 + - https://bugzilla.tianocore.org/show_bug.cgi?id=3D2168 + - https://bugzilla.tianocore.org/show_bug.cgi?id=3D1990 --=20 2.43.0 -=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 (#113759): https://edk2.groups.io/g/devel/message/113759 Mute This Topic: https://groups.io/mt/103689722/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 Wed May 15 19:16:36 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+113760+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+113760+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1705086964; cv=none; d=zohomail.com; s=zohoarc; b=kJeiSAJVnUMcq3JZ489wvR//kfjjNNTJRr0TKoTSV30BxqhHKZYNE6u352D3uhsYccQNKmYnw3g2+68H7EWDwrQUgSgVvmfkkzWyM487HbZtIUhK76uJb/X9oelE78neTSDqRrOZwObn/ZB93l9Df0p79Tj8TkRZ3EKVDWhWqg0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1705086964; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=Dqnxh38CtFgeakzPjlZQjD134ejNthT72QWGYUu+bIE=; b=aWHCrT5AHTyHkyFjUDsvR3p8Bv0RNHHTtbOyJnXADs3msyGGWX6u2DvIoKvH4w8m5LS35SzAoUUycr7DBvp4ruIGUZF4rPyAyvYUOG5XLOj5NZvPbRSW6jmtOQnBxikF9XJuqynElRa8Jk7DropDJRw26GBE7Q/JjHWQ5yF91jU= 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+113760+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1705086964162951.9508326967215; Fri, 12 Jan 2024 11:16:04 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=4D1GQ3lM3UuucMkBjsN7CDbIQuy1SjBPJyMF8nwwQYA=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1705086963; v=1; b=hSZal4bIZLKQ2PDxnUzHa8OZpaQU04uu3hOMtywdSLVNfwf2WuKR+mzVjoReknVQ5ZQbvrhL 2f8/JaeB3mXFZzJFjG0rbIb5OCErZr5rrLRG2cfgmxlOIj0MaElxuPEh/jM311kb0AW/9VZ3rJO uix/kVVDfti5Ue3O7TkzOTsY= X-Received: by 127.0.0.2 with SMTP id nS3eYY1788612xQjcOzuKSUA; Fri, 12 Jan 2024 11:16:03 -0800 X-Received: from mail-pl1-f180.google.com (mail-pl1-f180.google.com [209.85.214.180]) by mx.groups.io with SMTP id smtpd.web10.18730.1704997019038243760 for ; Thu, 11 Jan 2024 10:16:59 -0800 X-Received: by mail-pl1-f180.google.com with SMTP id d9443c01a7336-1d40eec5e12so46282275ad.1 for ; Thu, 11 Jan 2024 10:16:59 -0800 (PST) X-Gm-Message-State: UfYvENjHXMbgTvtx14VM4USKx1787277AA= X-Google-Smtp-Source: AGHT+IHKZ1M8C9NXnTUWK68f+m0oIfflHA0my132zQORrcSyiIydBJCJ7ByGv50G6nzZlIzth90SAw== X-Received: by 2002:a17:903:1306:b0:1d5:6a34:fb5c with SMTP id iy6-20020a170903130600b001d56a34fb5cmr124645plb.101.1704997017703; Thu, 11 Jan 2024 10:16:57 -0800 (PST) X-Received: from localhost.localdomain ([131.107.1.208]) by smtp.gmail.com with ESMTPSA id kd13-20020a17090313cd00b001d4752f5403sm1453414plb.206.2024.01.11.10.16.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Jan 2024 10:16:57 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: "Douglas Flick [MSFT]" , Jiewen Yao Subject: [edk2-devel] [PATCH 4/6] SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4118 - CVE 2022-36764 Date: Thu, 11 Jan 2024 10:16:04 -0800 Message-ID: <32af82809ace69a2711f0096cee91e7a7ad3aaae.1704996627.git.doug.edk2@gmail.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: 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,dougflick@microsoft.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1705086966238100022 Content-Type: text/plain; charset="utf-8" This commit contains the patch files and tests for DxeTpm2MeasureBootLib CVE 2022-36764. Cc: Jiewen Yao Signed-off-by: Doug Flick [MSFT] --- .../DxeTpm2MeasureBootLibSanitization.h | 28 ++++++++- .../DxeTpm2MeasureBootLib.c | 12 ++-- .../DxeTpm2MeasureBootLibSanitization.c | 46 +++++++++++++- .../DxeTpm2MeasureBootLibSanitizationTest.c | 60 ++++++++++++++++--- 4 files changed, 131 insertions(+), 15 deletions(-) diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLi= bSanitization.h b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureB= ootLibSanitization.h index 048b73898744..8f72ba42401f 100644 --- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSaniti= zation.h +++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSaniti= zation.h @@ -9,6 +9,9 @@ Tcg2MeasureGptTable() function will receive untrusted GPT partition tabl= e, and parse partition data carefully. =20 + Tcg2MeasurePeImage() function will accept untrusted PE/COFF image and va= lidate its + data structure within this image buffer before use. + Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -110,4 +113,27 @@ SanitizePrimaryHeaderGptEventSize ( OUT UINT32 *EventSize ); =20 -#endif // DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_ +/** + This function will validate that the PeImage Event Size from the loaded = image is sane + It will check the following: + - EventSize does not overflow + + @param[in] FilePathSize - Size of the file path. + @param[out] EventSize - Pointer to the event size. + + @retval EFI_SUCCESS + The event size is valid. + + @retval EFI_OUT_OF_RESOURCES + Overflow would have occurred. + + @retval EFI_INVALID_PARAMETER + One of the passed parameters was invalid. +**/ +EFI_STATUS +SanitizePeImageEventSize ( + IN UINT32 FilePathSize, + OUT UINT32 *EventSize + ); + +#endif // DXE_TPM2_MEASURE_BOOT_LIB_VALIDATION_ diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLi= b.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c index 0475103d6ef8..714cc8e03e80 100644 --- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c @@ -378,7 +378,6 @@ Exit: @retval EFI_OUT_OF_RESOURCES No enough resource to measure image. @retval EFI_UNSUPPORTED ImageType is unsupported or PE image is m= al-format. @retval other error value - **/ EFI_STATUS EFIAPI @@ -405,6 +404,7 @@ Tcg2MeasurePeImage ( Status =3D EFI_UNSUPPORTED; ImageLoad =3D NULL; EventPtr =3D NULL; + Tcg2Event =3D NULL; =20 Tcg2Protocol =3D MeasureBootProtocols->Tcg2Protocol; CcProtocol =3D MeasureBootProtocols->CcProtocol; @@ -420,18 +420,22 @@ Tcg2MeasurePeImage ( } =20 FilePathSize =3D (UINT32)GetDevicePathSize (FilePath); + Status =3D SanitizePeImageEventSize (FilePathSize, &EventSize); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } =20 // // Determine destination PCR by BootPolicy // - EventSize =3D sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + Fil= ePathSize; - EventPtr =3D AllocateZeroPool (EventSize + sizeof (EFI_TCG2_EVENT) - si= zeof (Tcg2Event->Event)); + // from a malicious GPT disk partition + EventPtr =3D AllocateZeroPool (EventSize); if (EventPtr =3D=3D NULL) { return EFI_OUT_OF_RESOURCES; } =20 Tcg2Event =3D (EFI_TCG2_EVENT *)EventPtr; - Tcg2Event->Size =3D EventSize + sizeof (EFI_TCG2_EVENT) = - sizeof (Tcg2Event->Event); + Tcg2Event->Size =3D EventSize; Tcg2Event->Header.HeaderSize =3D sizeof (EFI_TCG2_EVENT_HEADER); Tcg2Event->Header.HeaderVersion =3D EFI_TCG2_EVENT_HEADER_VERSION; ImageLoad =3D (EFI_IMAGE_LOAD_EVENT *)Tcg2Event->E= vent; diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLi= bSanitization.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureB= ootLibSanitization.c index e2309655d384..2a4d52c6d5cf 100644 --- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSaniti= zation.c +++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSaniti= zation.c @@ -151,7 +151,7 @@ SanitizeEfiPartitionTableHeader ( } =20 /** - This function will validate that the allocation size from the primary he= ader is sane + This function will validate that the allocation size from the primary hea= der is sane It will check the following: - AllocationSize does not overflow =20 @@ -273,3 +273,47 @@ SanitizePrimaryHeaderGptEventSize ( =20 return EFI_SUCCESS; } + +/** + This function will validate that the PeImage Event Size from the loaded = image is sane + It will check the following: + - EventSize does not overflow + + @param[in] FilePathSize - Size of the file path. + @param[out] EventSize - Pointer to the event size. + + @retval EFI_SUCCESS + The event size is valid. + + @retval EFI_OUT_OF_RESOURCES + Overflow would have occurred. + + @retval EFI_INVALID_PARAMETER + One of the passed parameters was invalid. +**/ +EFI_STATUS +SanitizePeImageEventSize ( + IN UINT32 FilePathSize, + OUT UINT32 *EventSize + ) +{ + EFI_STATUS Status; + + // Replacing logic: + // sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; + Status =3D SafeUint32Add (OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath), = FilePathSize, EventSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); + return EFI_BAD_BUFFER_SIZE; + } + + // Replacing logic: + // EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event) + Status =3D SafeUint32Add (*EventSize, OFFSET_OF (EFI_TCG2_EVENT, Event),= EventSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); + return EFI_BAD_BUFFER_SIZE; + } + + return EFI_SUCCESS; +} diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/Dxe= Tpm2MeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpm2MeasureBo= otLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c index 3eb9763e3c91..820e99aeb9b4 100644 --- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2Mea= sureBootLibSanitizationTest.c +++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2Mea= sureBootLibSanitizationTest.c @@ -72,10 +72,10 @@ TestSanitizeEfiPartitionTableHeader ( PrimaryHeader.Header.Revision =3D DEFAULT_PRIMARY_TABLE_HEADER_= REVISION; PrimaryHeader.Header.HeaderSize =3D sizeof (EFI_PARTITION_TABLE_H= EADER); PrimaryHeader.MyLBA =3D 1; - PrimaryHeader.AlternateLBA =3D 2; - PrimaryHeader.FirstUsableLBA =3D 3; - PrimaryHeader.LastUsableLBA =3D 4; - PrimaryHeader.PartitionEntryLBA =3D 5; + PrimaryHeader.PartitionEntryLBA =3D 2; + PrimaryHeader.AlternateLBA =3D 3; + PrimaryHeader.FirstUsableLBA =3D 4; + PrimaryHeader.LastUsableLBA =3D 5; PrimaryHeader.NumberOfPartitionEntries =3D DEFAULT_PRIMARY_TABLE_HEADER_= NUMBER_OF_PARTITION_ENTRIES; PrimaryHeader.SizeOfPartitionEntry =3D DEFAULT_PRIMARY_TABLE_HEADER_= SIZE_OF_PARTITION_ENTRY; PrimaryHeader.PartitionEntryArrayCRC32 =3D 0; // Purposely invalid @@ -187,11 +187,6 @@ TestSanitizePrimaryHeaderGptEventSize ( EFI_STATUS Status; EFI_PARTITION_TABLE_HEADER PrimaryHeader; UINTN NumberOfPartition; - EFI_GPT_DATA *GptData; - EFI_TCG2_EVENT *Tcg2Event; - - Tcg2Event =3D NULL; - GptData =3D NULL; =20 // Test that a normal PrimaryHeader passes validation PrimaryHeader.NumberOfPartitionEntries =3D 5; @@ -225,6 +220,52 @@ TestSanitizePrimaryHeaderGptEventSize ( return UNIT_TEST_PASSED; } =20 +/** + This function tests the SanitizePeImageEventSize function. + It's intent is to test that the untrusted input from a file path when ge= nerating a + EFI_IMAGE_LOAD_EVENT structure will not cause an overflow when calculati= ng + the event size when allocating space + + @param[in] Context The unit test context. + + @retval UNIT_TEST_PASSED The test passed. + @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. +**/ +UNIT_TEST_STATUS +EFIAPI +TestSanitizePeImageEventSize ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UINT32 EventSize; + UINTN ExistingLogicEventSize; + UINT32 FilePathSize; + EFI_STATUS Status; + + FilePathSize =3D 255; + + // Test that a normal PE image passes validation + Status =3D SanitizePeImageEventSize (FilePathSize, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_SUCCESS); + + // Test that the event size is correct compared to the existing logic + ExistingLogicEventSize =3D OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath)= + FilePathSize; + ExistingLogicEventSize +=3D OFFSET_OF (EFI_TCG2_EVENT, Event); + + if (EventSize !=3D ExistingLogicEventSize) { + UT_LOG_ERROR ("SanitizePeImageEventSize returned an incorrect event si= ze. Expected %u, got %u\n", ExistingLogicEventSize, EventSize); + return UNIT_TEST_ERROR_TEST_FAILED; + } + + // Test that the event size may not overflow + Status =3D SanitizePeImageEventSize (MAX_UINT32, &EventSize); + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE); + + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); + + return UNIT_TEST_PASSED; +} + // *--------------------------------------------------------------------* // * Unit Test Code Main Function // *--------------------------------------------------------------------* @@ -267,6 +308,7 @@ UefiTestMain ( AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Validating EF= I Partition Table", "Common.Tcg2MeasureBootLibValidation", TestSanitizeEfiP= artitionTableHeader, NULL, NULL, NULL); AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary heade= r gpt event checks for overflow", "Common.Tcg2MeasureBootLibValidation", Te= stSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary heade= r allocation size checks for overflow", "Common.Tcg2MeasureBootLibValidatio= n", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); + AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests PE Image and = FileSize checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestS= anitizePeImageEventSize, NULL, NULL, NULL); =20 Status =3D RunAllTestSuites (Framework); =20 --=20 2.43.0 -=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 (#113760): https://edk2.groups.io/g/devel/message/113760 Mute This Topic: https://groups.io/mt/103689723/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 Wed May 15 19:16:36 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+113761+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+113761+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1705086965; cv=none; d=zohomail.com; s=zohoarc; b=f+nY0On0+sTSjf+OYhN1Z6iRiX7qvTftdgPHvdiDVdCW0oiOXBdvM2L582Q6xQsED7t6naAoh+Lhz0N4KTG1cVWd8sYyZbnmoEAM4zHzvNFtBYDbaCQBSLjhug4jBzCHqO8zxrsbMlvDTTjfQlazeezc4Ev20gFIzF3n2KXBQO0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1705086965; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=zy73cBId5W8talAqDhFuM3Iq4QB9g3zHNrtgGTTCDZE=; b=O+vf2baJ1oTsCopW7DDNy3wP7FfGjSbkwNy2NjDLEuB9e8F3uFJ/rZzeQdBBUt562ZdvaDJ3576zofZYs4AmPQOQEx51HbwGkE+mc58j3ZmiaRZ7s/CZXoepXOw+ygXEFRIong7QkMrCHrmzr+aRgR6IMSYAwhyAypA2EquGFCw= 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+113761+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1705086965223229.70230527079104; Fri, 12 Jan 2024 11:16:05 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=dyUotW0eSl2tQSl9KET9zTM/jdAnwjDvLggYtw9Ep2g=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1705086964; v=1; b=Ut4T2gEGujDNmkVTyAMUa8uqjhhd5Xy07IB3kbN06xEMo1Yicp3p/iuslbYO0aMGc2TkSFih 6gXk8N3QopV3UJsKRah666MlvO0PRlLfyKR6VsxpVeT5KrIeCNde/o6pcVmcldT6bs8WoJY2vr4 bYYqlHwK3tRqiRkrJmxbQ0I8= X-Received: by 127.0.0.2 with SMTP id hDdbYY1788612xjnyzcdNsLl; Fri, 12 Jan 2024 11:16:04 -0800 X-Received: from mail-pl1-f173.google.com (mail-pl1-f173.google.com [209.85.214.173]) by mx.groups.io with SMTP id smtpd.web11.18613.1704997020484514044 for ; Thu, 11 Jan 2024 10:17:00 -0800 X-Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-1d3f2985425so29880745ad.3 for ; Thu, 11 Jan 2024 10:17:00 -0800 (PST) X-Gm-Message-State: VHxpvciyxCGyKvtPSRizSBbnx1787277AA= X-Google-Smtp-Source: AGHT+IF1OAOxjLfxXVpbbSpP8WlKIUt3RV2y4dTOg5ylVOgrejfBFn2u/wxVsZM/UZxT3nf+AvOJwA== X-Received: by 2002:a17:902:7b8b:b0:1d5:9452:74de with SMTP id w11-20020a1709027b8b00b001d5945274demr118140pll.72.1704997019471; Thu, 11 Jan 2024 10:16:59 -0800 (PST) X-Received: from localhost.localdomain ([131.107.1.208]) by smtp.gmail.com with ESMTPSA id kd13-20020a17090313cd00b001d4752f5403sm1453414plb.206.2024.01.11.10.16.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Jan 2024 10:16:59 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: "Douglas Flick [MSFT]" , Jiewen Yao Subject: [edk2-devel] [PATCH 5/6] SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4118 - CVE 2022-36764 Date: Thu, 11 Jan 2024 10:16:05 -0800 Message-ID: <548cfffb0ce8dc079af014a6b49077abef2642e8.1704996627.git.doug.edk2@gmail.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: 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,dougflick@microsoft.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1705086966217100021 Content-Type: text/plain; charset="utf-8" This commit contains the patch files and tests for DxeTpmMeasureBootLib CVE 2022-36764. Cc: Jiewen Yao Signed-off-by: Doug Flick [MSFT] --- .../DxeTpmMeasureBootLibSanitization.h | 23 +++++ .../DxeTpmMeasureBootLib.c | 13 ++- .../DxeTpmMeasureBootLibSanitization.c | 44 +++++++++ .../DxeTpmMeasureBootLibSanitizationTest.c | 98 +++++++++++++++++-- 4 files changed, 168 insertions(+), 10 deletions(-) diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibS= anitization.h b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootL= ibSanitization.h index 0d9d00c281f6..2248495813b5 100644 --- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitiza= tion.h +++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitiza= tion.h @@ -111,4 +111,27 @@ SanitizePrimaryHeaderGptEventSize ( OUT UINT32 *EventSize ); =20 +/** + This function will validate that the PeImage Event Size from the loaded = image is sane + It will check the following: + - EventSize does not overflow + + @param[in] FilePathSize - Size of the file path. + @param[out] EventSize - Pointer to the event size. + + @retval EFI_SUCCESS + The event size is valid. + + @retval EFI_OUT_OF_RESOURCES + Overflow would have occurred. + + @retval EFI_INVALID_PARAMETER + One of the passed parameters was invalid. +**/ +EFI_STATUS +SanitizePeImageEventSize ( + IN UINT32 FilePathSize, + OUT UINT32 *EventSize + ); + #endif // DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_ diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.= c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c index 669ab1913440..a9fc440a091e 100644 --- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c @@ -17,6 +17,7 @@ =20 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent +Copyright (c) Microsoft Corporation.
=20 Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -345,18 +346,22 @@ TcgMeasurePeImage ( ImageLoad =3D NULL; SectionHeader =3D NULL; Sha1Ctx =3D NULL; + TcgEvent =3D NULL; FilePathSize =3D (UINT32)GetDevicePathSize (FilePath); =20 - // // Determine destination PCR by BootPolicy // - EventSize =3D sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + Fil= ePathSize; - TcgEvent =3D AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT)); + Status =3D SanitizePeImageEventSize (FilePathSize, &EventSize); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + TcgEvent =3D AllocateZeroPool (EventSize); if (TcgEvent =3D=3D NULL) { return EFI_OUT_OF_RESOURCES; } =20 - TcgEvent->EventSize =3D EventSize; + TcgEvent->EventSize =3D EventSize - sizeof (TCG_PCR_EVENT_HDR); ImageLoad =3D (EFI_IMAGE_LOAD_EVENT *)TcgEvent->Event; =20 switch (ImageType) { diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibS= anitization.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootL= ibSanitization.c index a3fa46f5e632..c989851cec2d 100644 --- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitiza= tion.c +++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitiza= tion.c @@ -239,3 +239,47 @@ SanitizePrimaryHeaderGptEventSize ( =20 return EFI_SUCCESS; } + +/** + This function will validate that the PeImage Event Size from the loaded = image is sane + It will check the following: + - EventSize does not overflow + + @param[in] FilePathSize - Size of the file path. + @param[out] EventSize - Pointer to the event size. + + @retval EFI_SUCCESS + The event size is valid. + + @retval EFI_OUT_OF_RESOURCES + Overflow would have occurred. + + @retval EFI_INVALID_PARAMETER + One of the passed parameters was invalid. +**/ +EFI_STATUS +SanitizePeImageEventSize ( + IN UINT32 FilePathSize, + OUT UINT32 *EventSize + ) +{ + EFI_STATUS Status; + + // Replacing logic: + // sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize; + Status =3D SafeUint32Add (OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath), = FilePathSize, EventSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); + return EFI_BAD_BUFFER_SIZE; + } + + // Replacing logic: + // EventSize + sizeof (TCG_PCR_EVENT_HDR) + Status =3D SafeUint32Add (*EventSize, sizeof (TCG_PCR_EVENT_HDR), EventS= ize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n")); + return EFI_BAD_BUFFER_SIZE; + } + + return EFI_SUCCESS; +} diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeT= pmMeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpmMeasureBootL= ib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c index eeb928cdb0aa..c41498be4521 100644 --- a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasu= reBootLibSanitizationTest.c +++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasu= reBootLibSanitizationTest.c @@ -1,8 +1,8 @@ /** @file -This file includes the unit test cases for the DxeTpmMeasureBootLibSanitiz= ationTest.c. + This file includes the unit test cases for the DxeTpmMeasureBootLibSanit= izationTest.c. =20 -Copyright (c) Microsoft Corporation.
-SPDX-License-Identifier: BSD-2-Clause-Patent + Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/ =20 #include @@ -186,9 +186,6 @@ TestSanitizePrimaryHeaderGptEventSize ( EFI_STATUS Status; EFI_PARTITION_TABLE_HEADER PrimaryHeader; UINTN NumberOfPartition; - EFI_GPT_DATA *GptData; - - GptData =3D NULL; =20 // Test that a normal PrimaryHeader passes validation PrimaryHeader.NumberOfPartitionEntries =3D 5; @@ -222,6 +219,94 @@ TestSanitizePrimaryHeaderGptEventSize ( return UNIT_TEST_PASSED; } =20 +/** + This function tests the SanitizePeImageEventSize function. + It's intent is to test that the untrusted input from a file path for an + EFI_IMAGE_LOAD_EVENT structure will not cause an overflow when calculati= ng + the event size when allocating space. + + @param[in] Context The unit test context. + + @retval UNIT_TEST_PASSED The test passed. + @retval UNIT_TEST_ERROR_TEST_FAILED The test failed. +**/ +UNIT_TEST_STATUS +EFIAPI +TestSanitizePeImageEventSize ( + IN UNIT_TEST_CONTEXT Context + ) +{ + UINT32 EventSize; + UINTN ExistingLogicEventSize; + UINT32 FilePathSize; + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL DevicePath; + EFI_IMAGE_LOAD_EVENT *ImageLoadEvent; + UNIT_TEST_STATUS TestStatus; + + TestStatus =3D UNIT_TEST_ERROR_TEST_FAILED; + + // Generate EFI_DEVICE_PATH_PROTOCOL test data + DevicePath.Type =3D 0; + DevicePath.SubType =3D 0; + DevicePath.Length[0] =3D 0; + DevicePath.Length[1] =3D 0; + + // Generate EFI_IMAGE_LOAD_EVENT test data + ImageLoadEvent =3D AllocateZeroPool (sizeof (EFI_IMAGE_LOAD_EVENT) + siz= eof (EFI_DEVICE_PATH_PROTOCOL)); + if (ImageLoadEvent =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: AllocateZeroPool failed\n", __func__)); + goto Exit; + } + + // Populate EFI_IMAGE_LOAD_EVENT54 test data + ImageLoadEvent->ImageLocationInMemory =3D (EFI_PHYSICAL_ADDRESS)0x123456= 78; + ImageLoadEvent->ImageLengthInMemory =3D 0x1000; + ImageLoadEvent->ImageLinkTimeAddress =3D (UINTN)ImageLoadEvent; + ImageLoadEvent->LengthOfDevicePath =3D sizeof (EFI_DEVICE_PATH_PROTOC= OL); + CopyMem (ImageLoadEvent->DevicePath, &DevicePath, sizeof (EFI_DEVICE_PAT= H_PROTOCOL)); + + FilePathSize =3D 255; + + // Test that a normal PE image passes validation + Status =3D SanitizePeImageEventSize (FilePathSize, &EventSize); + if (EFI_ERROR (Status)) { + UT_LOG_ERROR ("SanitizePeImageEventSize failed with %r\n", Status); + goto Exit; + } + + // Test that the event size is correct compared to the existing logic + ExistingLogicEventSize =3D OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath)= + FilePathSize; + ExistingLogicEventSize +=3D sizeof (TCG_PCR_EVENT_HDR); + + if (EventSize !=3D ExistingLogicEventSize) { + UT_LOG_ERROR ("SanitizePeImageEventSize returned an incorrect event si= ze. Expected %u, got %u\n", ExistingLogicEventSize, EventSize); + goto Exit; + } + + // Test that the event size may not overflow + Status =3D SanitizePeImageEventSize (MAX_UINT32, &EventSize); + if (Status !=3D EFI_BAD_BUFFER_SIZE) { + UT_LOG_ERROR ("SanitizePeImageEventSize succeded when it was supposed = to fail with %r\n", Status); + goto Exit; + } + + TestStatus =3D UNIT_TEST_PASSED; +Exit: + + if (ImageLoadEvent !=3D NULL) { + FreePool (ImageLoadEvent); + } + + if (TestStatus =3D=3D UNIT_TEST_ERROR_TEST_FAILED) { + DEBUG ((DEBUG_ERROR, "%a: Test failed\n", __func__)); + } else { + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__)); + } + + return TestStatus; +} + // *--------------------------------------------------------------------* // * Unit Test Code Main Function // *--------------------------------------------------------------------* @@ -265,6 +350,7 @@ UefiTestMain ( AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Validating EFI= Partition Table", "Common.TcgMeasureBootLibValidation", TestSanitizeEfiPar= titionTableHeader, NULL, NULL, NULL); AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header= gpt event checks for overflow", "Common.TcgMeasureBootLibValidation", Test= SanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL); AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header= allocation size checks for overflow", "Common.TcgMeasureBootLibValidation"= , TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL); + AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests PE Image and F= ileSize checks for overflow", "Common.TcgMeasureBootLibValidation", TestSan= itizePeImageEventSize, NULL, NULL, NULL); =20 Status =3D RunAllTestSuites (Framework); =20 --=20 2.43.0 -=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 (#113761): https://edk2.groups.io/g/devel/message/113761 Mute This Topic: https://groups.io/mt/103689724/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 Wed May 15 19:16:36 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+113762+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+113762+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1705086966; cv=none; d=zohomail.com; s=zohoarc; b=j9oA4LfiNeb9aPD4DWusBlb4qPZ+NtUw78UDI30beSfE2BNG+MFz771uDuXAXSV4ucbTSVL6kggnLK0npSvRkY0XJkDxeH0WskukDJJtxsovmBrd5LICv2xaGYH194aPp20P5Siv43wydFs67EeWYtD/D/QXP4Ryj8+JmS5auso= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1705086966; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=D51XfrXt6cnS8t9gvI7y3nuRXrxbFu6l/WgbaN9ylgU=; b=EIEGpdoLHs0a9zHxYoWzHFXotmEu+qqHBy+f1zz7hFQDfvi4xkyc1z4kx7zUk1AMAVn2z40JCyZhNjFPmW+Wp7qTmRFochoavxZv5FkoypDaaZFumMWI0P9Mf0R+6JqlDNuqNAf1o9mtcvvG1AWuBjDdIftmo/OTpLZMsppAV94= 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+113762+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 170508696607491.61064354619373; Fri, 12 Jan 2024 11:16:06 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=2AjoO6nqyGOvRnMHc7mX92X8DW1BljGfhQAoe5e1H4k=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1705086965; v=1; b=UU12vGQS1wB5KTQ4rLbcgCBy90k3yLmfIGuNOjFHasAG42v1ZldY/Ze/3XWOZTKwpA2IqCJg RkNNO5Y/HTnC09Wx23J3qQwA871fDfSFMPQd87K0UhzIAEDKYbljeWi5ZAnRX/jes4aytcs7fIs mwEhJeUiP5inXmh/3Z481cVU= X-Received: by 127.0.0.2 with SMTP id OtVpYY1788612xvLn2hTQy9G; Fri, 12 Jan 2024 11:16:05 -0800 X-Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) by mx.groups.io with SMTP id smtpd.web10.18731.1704997022241465058 for ; Thu, 11 Jan 2024 10:17:02 -0800 X-Received: by mail-pl1-f178.google.com with SMTP id d9443c01a7336-1d509222c11so23561655ad.1 for ; Thu, 11 Jan 2024 10:17:02 -0800 (PST) X-Gm-Message-State: XGBo6WCOBucHUOy0dHP273Qnx1787277AA= X-Google-Smtp-Source: AGHT+IGk+kNqzIoZ0Z9OA8CcWqOfKZfF72l8jFhbfsgP+5WoTtlrFg/rqjJPdsib5I/9luXOkw9tgA== X-Received: by 2002:a17:902:ec8e:b0:1d4:b6e9:9e42 with SMTP id x14-20020a170902ec8e00b001d4b6e99e42mr157941plg.21.1704997020924; Thu, 11 Jan 2024 10:17:00 -0800 (PST) X-Received: from localhost.localdomain ([131.107.1.208]) by smtp.gmail.com with ESMTPSA id kd13-20020a17090313cd00b001d4752f5403sm1453414plb.206.2024.01.11.10.17.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Jan 2024 10:17:00 -0800 (PST) From: "Doug Flick via groups.io" To: devel@edk2.groups.io Cc: "Douglas Flick [MSFT]" , Jiewen Yao Subject: [edk2-devel] [PATCH 6/6] SecurityPkg: : Adding CVE 2022-36764 to SecurityFixes.yaml Date: Thu, 11 Jan 2024 10:16:06 -0800 Message-ID: <5a5085711066589ec66965191353853beaf1db81.1704996627.git.doug.edk2@gmail.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: 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,dougflick@microsoft.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1705086968140100034 Content-Type: text/plain; charset="utf-8" This creates / adds a security file that tracks the security fixes found in this package and can be used to find the fixes that were applied. Cc: Jiewen Yao Signed-off-by: Doug Flick [MSFT] --- SecurityPkg/SecurityFixes.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/SecurityPkg/SecurityFixes.yaml b/SecurityPkg/SecurityFixes.yaml index f9e3e7be7453..833fb827a96c 100644 --- a/SecurityPkg/SecurityFixes.yaml +++ b/SecurityPkg/SecurityFixes.yaml @@ -20,3 +20,17 @@ CVE_2022_36763: - https://bugzilla.tianocore.org/show_bug.cgi?id=3D4117 - https://bugzilla.tianocore.org/show_bug.cgi?id=3D2168 - https://bugzilla.tianocore.org/show_bug.cgi?id=3D1990 +CVE_2022_36764: + commit_titles: + - "SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4118 - CVE 2022= -36764" + - "SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4118 - CVE 2022-= 36764" + - "SecurityPkg: : Adding CVE 2022-36764 to SecurityFixes.yaml" + cve: CVE-2022-36764 + date_reported: 2022-10-25 12:23 UTC + description: Heap Buffer Overflow in Tcg2MeasurePeImage() + note: + files_impacted: + - Library\DxeTpm2MeasureBootLib\DxeTpm2MeasureBootLib.c + - Library\DxeTpmMeasureBootLib\DxeTpmMeasureBootLib.c + links: + - https://bugzilla.tianocore.org/show_bug.cgi?id=3D4118 --=20 2.43.0 -=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 (#113762): https://edk2.groups.io/g/devel/message/113762 Mute This Topic: https://groups.io/mt/103689725/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-