From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 9C0D6740034 for ; Fri, 12 Jan 2024 19:16:03 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=2/c7z3FOYwLNeoW5xMQeAHycV8tFRBq6O1obbyhKKsE=; 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=Ah5/KKgXsOuT5+0T8ZLhJL/bw7x/nRAkcd59EoBthanfh+ulZRUE/J4bYxJ2fK7iwMEltVBg tV1EYQvF/pFPRsBvxlJEXGM7hgKZpupXn4AB4RcMaeef7PzZJQ5cEUIqIHpdjcdwC9sMfl9PY9B ZMsOxXilO6jLMnr+lc+UcohM= X-Received: by 127.0.0.2 with SMTP id gl4rYY7687511x8ebizGxQiJ; 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: 1RnmKzrSs24Ctdz3hv4hxF3gx7686176AA= 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-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b="Ah5/KKgX"; dmarc=none; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io 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=0D SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf=0D SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/Moc= kPlatformPKProtectionLib.inf=0D + SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2Measur= eBootLibSanitizationTestHost.inf=0D =0D #=0D # Build SecurityPkg HOST_APPLICATION Tests=0D 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] =0D [Sources]=0D DxeTpm2MeasureBootLib.c=0D + DxeTpm2MeasureBootLibSanitization.c=0D + DxeTpm2MeasureBootLibSanitization.h=0D =0D [Packages]=0D MdePkg/MdePkg.dec=0D @@ -46,6 +48,7 @@ [Packages] =0D [LibraryClasses]=0D BaseMemoryLib=0D + SafeIntLib=0D DebugLib=0D MemoryAllocationLib=0D DevicePathLib=0D @@ -65,4 +68,3 @@ [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES=0D gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES=0D gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES=0D -=0D 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=0D +# This file builds the unit tests for DxeTpm2MeasureBootLib=0D +#=0D +# Copyright (C) Microsoft Corporation.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x00010006=0D + BASE_NAME =3D DxeTpm2MeasuredBootLibTest=0D + FILE_GUID =3D 144d757f-d423-484e-9309-a23695fad5bd= =0D + MODULE_TYPE =3D HOST_APPLICATION=0D + VERSION_STRING =3D 1.0=0D + ENTRY_POINT =3D main=0D +=0D +[Sources]=0D + DxeTpm2MeasureBootLibSanitizationTest.c=0D + ../DxeTpm2MeasureBootLibSanitization.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + DebugLib=0D + UnitTestLib=0D + PrintLib=0D + SafeIntLib=0D 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=0D + This file includes the function prototypes for the sanitization function= s.=0D +=0D + These are those functions:=0D +=0D + DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF ima= ge content=0D + read is within the image buffer.=0D +=0D + Tcg2MeasureGptTable() function will receive untrusted GPT partition tabl= e, and parse=0D + partition data carefully.=0D +=0D + Copyright (c) Microsoft Corporation.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_=0D +#define DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +/**=0D + This function will validate the EFI_PARTITION_TABLE_HEADER structure is = safe to parse=0D + However this function will not attempt to verify the validity of the GPT= partition=0D + It will check the following:=0D + - Signature=0D + - Revision=0D + - AlternateLBA=0D + - FirstUsableLBA=0D + - LastUsableLBA=0D + - PartitionEntryLBA=0D + - NumberOfPartitionEntries=0D + - SizeOfPartitionEntry=0D + - BlockIo=0D +=0D + @param[in] PrimaryHeader=0D + Pointer to the EFI_PARTITION_TABLE_HEADER structure.=0D +=0D + @param[in] BlockIo=0D + Pointer to the EFI_BLOCK_IO_PROTOCOL structure.=0D +=0D + @retval EFI_SUCCESS=0D + The EFI_PARTITION_TABLE_HEADER structure is valid.=0D +=0D + @retval EFI_INVALID_PARAMETER=0D + The EFI_PARTITION_TABLE_HEADER structure is invalid.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SanitizeEfiPartitionTableHeader (=0D + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,=0D + IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo=0D + );=0D +=0D +/**=0D + This function will validate that the allocation size from the primary he= ader is sane=0D + It will check the following:=0D + - AllocationSize does not overflow=0D +=0D + @param[in] PrimaryHeader=0D + Pointer to the EFI_PARTITION_TABLE_HEADER structure.=0D +=0D + @param[out] AllocationSize=0D + Pointer to the allocation size.=0D +=0D + @retval EFI_SUCCESS=0D + The allocation size is valid.=0D +=0D + @retval EFI_OUT_OF_RESOURCES=0D + The allocation size is invalid.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SanitizePrimaryHeaderAllocationSize (=0D + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,=0D + OUT UINT32 *AllocationSize=0D + );=0D +=0D +/**=0D + This function will validate that the Gpt Event Size calculated from the = primary header is sane=0D + It will check the following:=0D + - EventSize does not overflow=0D +=0D + Important: This function includes the entire length of the allocated spa= ce, including=0D + (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) . When hashing the= buffer allocated with this=0D + size, the caller must subtract the size of the (sizeof (EFI_TCG2_EVENT) = - sizeof (Tcg2Event->Event))=0D + from the size of the buffer before hashing.=0D +=0D + @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER str= ucture.=0D + @param[in] NumberOfPartition - Number of partitions.=0D + @param[out] EventSize - Pointer to the event size.=0D +=0D + @retval EFI_SUCCESS=0D + The event size is valid.=0D +=0D + @retval EFI_OUT_OF_RESOURCES=0D + Overflow would have occurred.=0D +=0D + @retval EFI_INVALID_PARAMETER=0D + One of the passed parameters was invalid.=0D +**/=0D +EFI_STATUS=0D +SanitizePrimaryHeaderGptEventSize (=0D + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,=0D + IN UINTN NumberOfPartition,=0D + OUT UINT32 *EventSize=0D + );=0D +=0D +#endif // DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_=0D 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
=0D SPDX-License-Identifier: BSD-2-Clause-Patent=0D =0D +Copyright (c) Microsoft Corporation.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D **/=0D =0D #include =0D @@ -44,6 +46,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include =0D #include =0D =0D +#include "DxeTpm2MeasureBootLibSanitization.h"=0D +=0D typedef struct {=0D EFI_TCG2_PROTOCOL *Tcg2Protocol;=0D EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol;=0D @@ -144,10 +148,11 @@ Tcg2MeasureGptTable ( EFI_TCG2_EVENT *Tcg2Event;=0D EFI_CC_EVENT *CcEvent;=0D EFI_GPT_DATA *GptData;=0D - UINT32 EventSize;=0D + UINT32 TcgEventSize;=0D EFI_TCG2_PROTOCOL *Tcg2Protocol;=0D EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol;=0D EFI_CC_MR_INDEX MrIndex;=0D + UINT32 AllocSize;=0D =0D if (mTcg2MeasureGptCount > 0) {=0D return EFI_SUCCESS;=0D @@ -195,25 +200,22 @@ Tcg2MeasureGptTable ( BlockIo->Media->BlockSize,=0D (UINT8 *)PrimaryHeader=0D );=0D - if (EFI_ERROR (Status)) {=0D - DEBUG ((DEBUG_ERROR, "Failed to Read Partition Table Header!\n"));=0D + if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (Pr= imaryHeader, BlockIo))) {=0D + DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid= Partition Table Header!\n"));=0D FreePool (PrimaryHeader);=0D return EFI_DEVICE_ERROR;=0D }=0D =0D - //=0D - // PrimaryHeader->SizeOfPartitionEntry should not be zero=0D - //=0D - if (PrimaryHeader->SizeOfPartitionEntry =3D=3D 0) {=0D - DEBUG ((DEBUG_ERROR, "SizeOfPartitionEntry should not be zero!\n"));=0D - FreePool (PrimaryHeader);=0D - return EFI_BAD_BUFFER_SIZE;=0D - }=0D -=0D //=0D // Read the partition entry.=0D //=0D - EntryPtr =3D (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntr= ies * PrimaryHeader->SizeOfPartitionEntry);=0D + Status =3D SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSiz= e);=0D + if (EFI_ERROR (Status)) {=0D + FreePool (PrimaryHeader);=0D + return EFI_BAD_BUFFER_SIZE;=0D + }=0D +=0D + EntryPtr =3D (UINT8 *)AllocatePool (AllocSize);=0D if (EntryPtr =3D=3D NULL) {=0D FreePool (PrimaryHeader);=0D return EFI_OUT_OF_RESOURCES;=0D @@ -223,7 +225,7 @@ Tcg2MeasureGptTable ( DiskIo,=0D BlockIo->Media->MediaId,=0D MultU64x32 (PrimaryHeader->PartitionEntryLBA, BlockIo= ->Media->BlockSize),=0D - PrimaryHeader->NumberOfPartitionEntries * PrimaryHead= er->SizeOfPartitionEntry,=0D + AllocSize,=0D EntryPtr=0D );=0D if (EFI_ERROR (Status)) {=0D @@ -248,16 +250,21 @@ Tcg2MeasureGptTable ( //=0D // Prepare Data for Measurement (CcProtocol and Tcg2Protocol)=0D //=0D - EventSize =3D (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitio= ns)=0D - + NumberOfPartition * PrimaryHeader->SizeOfPartitio= nEntry);=0D - EventPtr =3D (UINT8 *)AllocateZeroPool (EventSize + sizeof (EFI_TCG2_EVE= NT) - sizeof (Tcg2Event->Event));=0D + Status =3D SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPar= tition, &TcgEventSize);=0D + if (EFI_ERROR (Status)) {=0D + FreePool (PrimaryHeader);=0D + FreePool (EntryPtr);=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + EventPtr =3D (UINT8 *)AllocateZeroPool (TcgEventSize);=0D if (EventPtr =3D=3D NULL) {=0D Status =3D EFI_OUT_OF_RESOURCES;=0D goto Exit;=0D }=0D =0D Tcg2Event =3D (EFI_TCG2_EVENT *)EventPtr;=0D - Tcg2Event->Size =3D EventSize + sizeof (EFI_TCG2_EVENT) = - sizeof (Tcg2Event->Event);=0D + Tcg2Event->Size =3D TcgEventSize;=0D Tcg2Event->Header.HeaderSize =3D sizeof (EFI_TCG2_EVENT_HEADER);=0D Tcg2Event->Header.HeaderVersion =3D EFI_TCG2_EVENT_HEADER_VERSION;=0D Tcg2Event->Header.PCRIndex =3D 5;=0D @@ -310,7 +317,7 @@ Tcg2MeasureGptTable ( CcProtocol,=0D 0,=0D (EFI_PHYSICAL_ADDRESS)(UINTN)(= VOID *)GptData,=0D - (UINT64)EventSize,=0D + (UINT64)TcgEventSize - OFFSET_= OF (EFI_TCG2_EVENT, Event),=0D CcEvent=0D );=0D if (!EFI_ERROR (Status)) {=0D @@ -326,7 +333,7 @@ Tcg2MeasureGptTable ( Tcg2Protocol,=0D 0,=0D (EFI_PHYSICAL_ADDRESS)(UINTN)(VOID *)GptData,= =0D - (UINT64)EventSize,=0D + (UINT64)TcgEventSize - OFFSET_OF (EFI_TCG2_E= VENT, Event),=0D Tcg2Event=0D );=0D if (!EFI_ERROR (Status)) {=0D @@ -443,11 +450,13 @@ Tcg2MeasurePeImage ( Tcg2Event->Header.PCRIndex =3D 2;=0D break;=0D default:=0D - DEBUG ((=0D - DEBUG_ERROR,=0D - "Tcg2MeasurePeImage: Unknown subsystem type %d",=0D - ImageType=0D - ));=0D + DEBUG (=0D + (=0D + DEBUG_ERROR,=0D + "Tcg2MeasurePeImage: Unknown subsystem type %d",=0D + ImageType=0D + )=0D + );=0D goto Finish;=0D }=0D =0D @@ -515,7 +524,7 @@ Finish: =0D @param MeasureBootProtocols Pointer to the located measure boot protoc= ol instances.=0D =0D - @retval EFI_SUCCESS Sucessfully locate the measure boot protoc= ol instances (at least one instance).=0D + @retval EFI_SUCCESS Successfully locate the measure boot proto= col instances (at least one instance).=0D @retval EFI_UNSUPPORTED Measure boot is not supported.=0D **/=0D EFI_STATUS=0D @@ -646,12 +655,14 @@ DxeTpm2MeasureBootHandler ( return EFI_SUCCESS;=0D }=0D =0D - DEBUG ((=0D - DEBUG_INFO,=0D - "Tcg2Protocol =3D %p, CcMeasurementProtocol =3D %p\n",=0D - MeasureBootProtocols.Tcg2Protocol,=0D - MeasureBootProtocols.CcProtocol=0D - ));=0D + DEBUG (=0D + (=0D + DEBUG_INFO,=0D + "Tcg2Protocol =3D %p, CcMeasurementProtocol =3D %p\n",=0D + MeasureBootProtocols.Tcg2Protocol,=0D + MeasureBootProtocols.CcProtocol=0D + )=0D + );=0D =0D //=0D // Copy File Device Path=0D 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=0D + The library instance provides security service of TPM2 measure boot and= =0D + Confidential Computing (CC) measure boot.=0D +=0D + Caution: This file requires additional review when modified.=0D + This library will have external input - PE/COFF image and GPT partition.= =0D + This external input must be validated carefully to avoid security issue = like=0D + buffer overflow, integer overflow.=0D +=0D + This file will pull out the validation logic from the following function= s, in an=0D + attempt to validate the untrusted input in the form of unit tests=0D +=0D + These are those functions:=0D +=0D + DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF ima= ge content=0D + read is within the image buffer.=0D +=0D + Tcg2MeasureGptTable() function will receive untrusted GPT partition tabl= e, and parse=0D + partition data carefully.=0D +=0D + Copyright (c) Microsoft Corporation.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +#include "DxeTpm2MeasureBootLibSanitization.h"=0D +=0D +#define GPT_HEADER_REVISION_V1 0x00010000=0D +=0D +/**=0D + This function will validate the EFI_PARTITION_TABLE_HEADER structure is = safe to parse=0D + However this function will not attempt to verify the validity of the GPT= partition=0D + It will check the following:=0D + - Signature=0D + - Revision=0D + - AlternateLBA=0D + - FirstUsableLBA=0D + - LastUsableLBA=0D + - PartitionEntryLBA=0D + - NumberOfPartitionEntries=0D + - SizeOfPartitionEntry=0D + - BlockIo=0D +=0D + @param[in] PrimaryHeader=0D + Pointer to the EFI_PARTITION_TABLE_HEADER structure.=0D +=0D + @param[in] BlockIo=0D + Pointer to the EFI_BLOCK_IO_PROTOCOL structure.=0D +=0D + @retval EFI_SUCCESS=0D + The EFI_PARTITION_TABLE_HEADER structure is valid.=0D +=0D + @retval EFI_INVALID_PARAMETER=0D + The EFI_PARTITION_TABLE_HEADER structure is invalid.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SanitizeEfiPartitionTableHeader (=0D + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,=0D + IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo=0D + )=0D +{=0D + //=0D + // Verify that the input parameters are safe to use=0D + //=0D + if (PrimaryHeader =3D=3D NULL) {=0D + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n"));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if ((BlockIo =3D=3D NULL) || (BlockIo->Media =3D=3D NULL)) {=0D + DEBUG ((DEBUG_ERROR, "Invalid BlockIo!\n"));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // The signature must be EFI_PTAB_HEADER_ID ("EFI PART" in ASCII)=0D + //=0D + if (PrimaryHeader->Header.Signature !=3D EFI_PTAB_HEADER_ID) {=0D + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n"));=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + //=0D + // The version must be GPT_HEADER_REVISION_V1 (0x00010000)=0D + //=0D + if (PrimaryHeader->Header.Revision !=3D GPT_HEADER_REVISION_V1) {=0D + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header Revision!\n"));=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + //=0D + // The HeaderSize must be greater than or equal to 92 and must be less t= han or equal to the logical block size=0D + //=0D + if ((PrimaryHeader->Header.HeaderSize < sizeof (EFI_PARTITION_TABLE_HEAD= ER)) || (PrimaryHeader->Header.HeaderSize > BlockIo->Media->BlockSize)) {=0D + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header HeaderSize!\n"));= =0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + //=0D + // The partition entries should all be before the first usable block=0D + //=0D + if (PrimaryHeader->FirstUsableLBA <=3D PrimaryHeader->PartitionEntryLBA)= {=0D + DEBUG ((DEBUG_ERROR, "GPT PartitionEntryLBA is not less than FirstUsab= leLBA!\n"));=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + //=0D + // Check that the PartitionEntryLBA greater than the Max LBA=0D + // This will be used later for multiplication=0D + //=0D + if (PrimaryHeader->PartitionEntryLBA > DivU64x32 (MAX_UINT64, BlockIo->M= edia->BlockSize)) {=0D + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header PartitionEntryLBA= !\n"));=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + //=0D + // Check that the number of partition entries is greater than zero=0D + //=0D + if (PrimaryHeader->NumberOfPartitionEntries =3D=3D 0) {=0D + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartition= Entries!\n"));=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + //=0D + // SizeOfPartitionEntry must be 128, 256, 512... improper size may lead = to accessing uninitialized memory=0D + //=0D + if ((PrimaryHeader->SizeOfPartitionEntry < 128) || ((PrimaryHeader->Size= OfPartitionEntry & (PrimaryHeader->SizeOfPartitionEntry - 1)) !=3D 0)) {=0D + 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"));=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + //=0D + // This check is to prevent overflow when calculating the allocation siz= e for the partition entries=0D + // This check will be used later for multiplication=0D + //=0D + if (PrimaryHeader->NumberOfPartitionEntries > DivU64x32 (MAX_UINT64, Pri= maryHeader->SizeOfPartitionEntry)) {=0D + DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartition= Entries!\n"));=0D + return EFI_DEVICE_ERROR;=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This function will validate that the allocation size from the primary he= ader is sane=0D + It will check the following:=0D + - AllocationSize does not overflow=0D +=0D + @param[in] PrimaryHeader=0D + Pointer to the EFI_PARTITION_TABLE_HEADER structure.=0D +=0D + @param[out] AllocationSize=0D + Pointer to the allocation size.=0D +=0D + @retval EFI_SUCCESS=0D + The allocation size is valid.=0D +=0D + @retval EFI_OUT_OF_RESOURCES=0D + The allocation size is invalid.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SanitizePrimaryHeaderAllocationSize (=0D + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,=0D + OUT UINT32 *AllocationSize=0D + )=0D +{=0D + EFI_STATUS Status;=0D +=0D + if (PrimaryHeader =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (AllocationSize =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Replacing logic:=0D + // PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartit= ionEntry;=0D + //=0D + Status =3D SafeUint32Mult (PrimaryHeader->NumberOfPartitionEntries, Prim= aryHeader->SizeOfPartitionEntry, AllocationSize);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Allocation Size would have overflowed!\n"));=0D + return EFI_BAD_BUFFER_SIZE;=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This function will validate that the Gpt Event Size calculated from the = primary header is sane=0D + It will check the following:=0D + - EventSize does not overflow=0D +=0D + Important: This function includes the entire length of the allocated spa= ce, including=0D + (sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event)) . When hashing the= buffer allocated with this=0D + size, the caller must subtract the size of the (sizeof (EFI_TCG2_EVENT) = - sizeof (Tcg2Event->Event))=0D + from the size of the buffer before hashing.=0D +=0D + @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER str= ucture.=0D + @param[in] NumberOfPartition - Number of partitions.=0D + @param[out] EventSize - Pointer to the event size.=0D +=0D + @retval EFI_SUCCESS=0D + The event size is valid.=0D +=0D + @retval EFI_OUT_OF_RESOURCES=0D + Overflow would have occurred.=0D +=0D + @retval EFI_INVALID_PARAMETER=0D + One of the passed parameters was invalid.=0D +**/=0D +EFI_STATUS=0D +SanitizePrimaryHeaderGptEventSize (=0D + IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,=0D + IN UINTN NumberOfPartition,=0D + OUT UINT32 *EventSize=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINT32 SafeNumberOfPartitions;=0D +=0D + if (PrimaryHeader =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (EventSize =3D=3D NULL) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // We shouldn't even attempt to perform the multiplication if the number= of partitions is greater than the maximum value of UINT32=0D + //=0D + Status =3D SafeUintnToUint32 (NumberOfPartition, &SafeNumberOfPartitions= );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "NumberOfPartition would have overflowed!\n"));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Replacing logic:=0D + // (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) + Numbe= rOfPartition * PrimaryHeader.SizeOfPartitionEntry);=0D + //=0D + Status =3D SafeUint32Mult (SafeNumberOfPartitions, PrimaryHeader->SizeOf= PartitionEntry, EventSize);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Event Size would have overflowed!\n"));=0D + return EFI_BAD_BUFFER_SIZE;=0D + }=0D +=0D + //=0D + // Replacing logic:=0D + // *EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event);=0D + //=0D + Status =3D SafeUint32Add (=0D + OFFSET_OF (EFI_TCG2_EVENT, Event) + OFFSET_OF (EFI_GPT_DATA, = Partitions),=0D + *EventSize,=0D + EventSize=0D + );=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "Event Size would have overflowed because of GPTD= ata!\n"));=0D + return EFI_BAD_BUFFER_SIZE;=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D 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=0D + This file includes the unit test cases for the DxeTpm2MeasureBootLibSani= tizationTest.c.=0D +=0D + Copyright (c) Microsoft Corporation.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +#include "../DxeTpm2MeasureBootLibSanitization.h"=0D +=0D +#define UNIT_TEST_NAME "DxeTpm2MeasureBootLibSanitizationTest"=0D +#define UNIT_TEST_VERSION "1.0"=0D +=0D +#define DEFAULT_PRIMARY_TABLE_HEADER_REVISION 0x000100= 00=0D +#define DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES 1=0D +#define DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY 128=0D +=0D +/**=0D + This function tests the SanitizeEfiPartitionTableHeader function.=0D + It's intent is to test that a malicious EFI_PARTITION_TABLE_HEADER=0D + structure will not cause undefined or unexpected behavior.=0D +=0D + In general the TPM should still be able to measure the data, but=0D + be the header should be sanitized to prevent any unexpected behavior.=0D +=0D + @param[in] Context The unit test context.=0D +=0D + @retval UNIT_TEST_PASSED The test passed.=0D + @retval UNIT_TEST_ERROR_TEST_FAILED The test failed.=0D +**/=0D +UNIT_TEST_STATUS=0D +EFIAPI=0D +TestSanitizeEfiPartitionTableHeader (=0D + IN UNIT_TEST_CONTEXT Context=0D + )=0D +{=0D + EFI_STATUS Status;=0D + EFI_PARTITION_TABLE_HEADER PrimaryHeader;=0D + EFI_BLOCK_IO_PROTOCOL BlockIo;=0D + EFI_BLOCK_IO_MEDIA BlockMedia;=0D +=0D + // Generate EFI_BLOCK_IO_MEDIA test data=0D + BlockMedia.MediaId =3D 1;=0D + BlockMedia.RemovableMedia =3D FALSE;=0D + BlockMedia.MediaPresent =3D TRUE;=0D + BlockMedia.LogicalPartition =3D FALSE;=0D + BlockMedia.ReadOnly =3D FALSE;=0D + BlockMedia.WriteCaching =3D FALSE;=0D + BlockMedia.BlockSize =3D 512;=0D + BlockMedia.IoAlign =3D 1;=0D + BlockMedia.LastBlock =3D 0;=0D +=0D + // Generate EFI_BLOCK_IO_PROTOCOL test data=0D + BlockIo.Revision =3D 1;=0D + BlockIo.Media =3D &BlockMedia;=0D + BlockIo.Reset =3D NULL;=0D + BlockIo.ReadBlocks =3D NULL;=0D + BlockIo.WriteBlocks =3D NULL;=0D + BlockIo.FlushBlocks =3D NULL;=0D +=0D + // Geneate EFI_PARTITION_TABLE_HEADER test data=0D + PrimaryHeader.Header.Signature =3D EFI_PTAB_HEADER_ID;=0D + PrimaryHeader.Header.Revision =3D DEFAULT_PRIMARY_TABLE_HEADER_= REVISION;=0D + PrimaryHeader.Header.HeaderSize =3D sizeof (EFI_PARTITION_TABLE_H= EADER);=0D + PrimaryHeader.MyLBA =3D 1;=0D + PrimaryHeader.AlternateLBA =3D 2;=0D + PrimaryHeader.FirstUsableLBA =3D 3;=0D + PrimaryHeader.LastUsableLBA =3D 4;=0D + PrimaryHeader.PartitionEntryLBA =3D 5;=0D + PrimaryHeader.NumberOfPartitionEntries =3D DEFAULT_PRIMARY_TABLE_HEADER_= NUMBER_OF_PARTITION_ENTRIES;=0D + PrimaryHeader.SizeOfPartitionEntry =3D DEFAULT_PRIMARY_TABLE_HEADER_= SIZE_OF_PARTITION_ENTRY;=0D + PrimaryHeader.PartitionEntryArrayCRC32 =3D 0; // Purposely invalid=0D +=0D + // Calculate the CRC32 of the PrimaryHeader=0D + PrimaryHeader.Header.CRC32 =3D CalculateCrc32 ((UINT8 *)&PrimaryHeader, = PrimaryHeader.Header.HeaderSize);=0D +=0D + // Test that a normal PrimaryHeader passes validation=0D + Status =3D SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);=0D + UT_ASSERT_NOT_EFI_ERROR (Status);=0D +=0D + // Test that when number of partition entries is 0, the function returns= EFI_DEVICE_ERROR=0D + // Should print "Invalid Partition Table Header NumberOfPartitionEntries= !""=0D + PrimaryHeader.NumberOfPartitionEntries =3D 0;=0D + Status =3D SanitizeEfiPartitionTableHead= er (&PrimaryHeader, &BlockIo);=0D + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR);=0D + PrimaryHeader.NumberOfPartitionEntries =3D DEFAULT_PRIMARY_TABLE_HEADER_= SIZE_OF_PARTITION_ENTRY;=0D +=0D + // Test that when the header size is too small, the function returns EFI= _DEVICE_ERROR=0D + // Should print "Invalid Partition Table Header Size!"=0D + PrimaryHeader.Header.HeaderSize =3D 0;=0D + Status =3D SanitizeEfiPartitionTableHeader (&Pr= imaryHeader, &BlockIo);=0D + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR);=0D + PrimaryHeader.Header.HeaderSize =3D sizeof (EFI_PARTITION_TABLE_HEADER);= =0D +=0D + // Test that when the SizeOfPartitionEntry is too small, the function re= turns EFI_DEVICE_ERROR=0D + // 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.)!"=0D + PrimaryHeader.SizeOfPartitionEntry =3D 1;=0D + Status =3D SanitizeEfiPartitionTableHeader (= &PrimaryHeader, &BlockIo);=0D + UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR);=0D +=0D + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__));=0D +=0D + return UNIT_TEST_PASSED;=0D +}=0D +=0D +/**=0D + This function tests the SanitizePrimaryHeaderAllocationSize function.=0D + It's intent is to test that the untrusted input from a EFI_PARTITION_TAB= LE_HEADER=0D + structure will not cause an overflow when calculating the allocation siz= e.=0D +=0D + @param[in] Context The unit test context.=0D +=0D + @retval UNIT_TEST_PASSED The test passed.=0D + @retval UNIT_TEST_ERROR_TEST_FAILED The test failed.=0D +**/=0D +UNIT_TEST_STATUS=0D +EFIAPI=0D +TestSanitizePrimaryHeaderAllocationSize (=0D + IN UNIT_TEST_CONTEXT Context=0D + )=0D +{=0D + UINT32 AllocationSize;=0D +=0D + EFI_STATUS Status;=0D + EFI_PARTITION_TABLE_HEADER PrimaryHeader;=0D +=0D + // Test that a normal PrimaryHeader passes validation=0D + PrimaryHeader.NumberOfPartitionEntries =3D 5;=0D + PrimaryHeader.SizeOfPartitionEntry =3D DEFAULT_PRIMARY_TABLE_HEADER_= SIZE_OF_PARTITION_ENTRY;=0D +=0D + Status =3D SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &Allocat= ionSize);=0D + UT_ASSERT_NOT_EFI_ERROR (Status);=0D +=0D + // Test that the allocation size is correct compared to the existing log= ic=0D + UT_ASSERT_EQUAL (AllocationSize, PrimaryHeader.NumberOfPartitionEntries = * PrimaryHeader.SizeOfPartitionEntry);=0D +=0D + // Test that an overflow is detected=0D + PrimaryHeader.NumberOfPartitionEntries =3D MAX_UINT32;=0D + PrimaryHeader.SizeOfPartitionEntry =3D 5;=0D + Status =3D SanitizePrimaryHeaderAllocati= onSize (&PrimaryHeader, &AllocationSize);=0D + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);=0D +=0D + // Test the inverse=0D + PrimaryHeader.NumberOfPartitionEntries =3D 5;=0D + PrimaryHeader.SizeOfPartitionEntry =3D MAX_UINT32;=0D + Status =3D SanitizePrimaryHeaderAllocati= onSize (&PrimaryHeader, &AllocationSize);=0D + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);=0D +=0D + // Test the worst case scenario=0D + PrimaryHeader.NumberOfPartitionEntries =3D MAX_UINT32;=0D + PrimaryHeader.SizeOfPartitionEntry =3D MAX_UINT32;=0D + Status =3D SanitizePrimaryHeaderAllocati= onSize (&PrimaryHeader, &AllocationSize);=0D + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);=0D +=0D + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__));=0D +=0D + return UNIT_TEST_PASSED;=0D +}=0D +=0D +/**=0D + This function tests the SanitizePrimaryHeaderGptEventSize function.=0D + It's intent is to test that the untrusted input from a EFI_GPT_DATA stru= cture=0D + will not cause an overflow when calculating the event size.=0D +=0D + @param[in] Context The unit test context.=0D +=0D + @retval UNIT_TEST_PASSED The test passed.=0D + @retval UNIT_TEST_ERROR_TEST_FAILED The test failed.=0D +**/=0D +UNIT_TEST_STATUS=0D +EFIAPI=0D +TestSanitizePrimaryHeaderGptEventSize (=0D + IN UNIT_TEST_CONTEXT Context=0D + )=0D +{=0D + UINT32 EventSize;=0D + UINT32 ExistingLogicEventSize;=0D + EFI_STATUS Status;=0D + EFI_PARTITION_TABLE_HEADER PrimaryHeader;=0D + UINTN NumberOfPartition;=0D + EFI_GPT_DATA *GptData;=0D + EFI_TCG2_EVENT *Tcg2Event;=0D +=0D + Tcg2Event =3D NULL;=0D + GptData =3D NULL;=0D +=0D + // Test that a normal PrimaryHeader passes validation=0D + PrimaryHeader.NumberOfPartitionEntries =3D 5;=0D + PrimaryHeader.SizeOfPartitionEntry =3D DEFAULT_PRIMARY_TABLE_HEADER_= SIZE_OF_PARTITION_ENTRY;=0D +=0D + // set the number of partitions=0D + NumberOfPartition =3D 13;=0D +=0D + // that the primary event size is correct=0D + Status =3D SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPa= rtition, &EventSize);=0D + UT_ASSERT_NOT_EFI_ERROR (Status);=0D +=0D + // Calculate the existing logic event size=0D + ExistingLogicEventSize =3D (UINT32)(OFFSET_OF (EFI_TCG2_EVENT, Event) + = OFFSET_OF (EFI_GPT_DATA, Partitions)=0D + + NumberOfPartition * PrimaryHeader.Si= zeOfPartitionEntry);=0D +=0D + // Check that the event size is correct=0D + UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize);=0D +=0D + // Tests that the primary event size may not overflow=0D + Status =3D SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32= , &EventSize);=0D + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);=0D +=0D + // Test that the size of partition entries may not overflow=0D + PrimaryHeader.SizeOfPartitionEntry =3D MAX_UINT32;=0D + Status =3D SanitizePrimaryHeaderGptEventSize= (&PrimaryHeader, NumberOfPartition, &EventSize);=0D + UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);=0D +=0D + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__));=0D +=0D + return UNIT_TEST_PASSED;=0D +}=0D +=0D +// *--------------------------------------------------------------------*= =0D +// * Unit Test Code Main Function=0D +// *--------------------------------------------------------------------*= =0D +=0D +/**=0D + This function acts as the entry point for the unit tests.=0D +=0D + @retval UNIT_TEST_PASSED The test passed.=0D + @retval UNIT_TEST_ERROR_TEST_FAILED The test failed.=0D + @retval others The test failed.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +UefiTestMain (=0D + VOID=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UNIT_TEST_FRAMEWORK_HANDLE Framework;=0D + UNIT_TEST_SUITE_HANDLE Tcg2MeasureBootLibValidationTestSuite;=0D +=0D + Framework =3D NULL;=0D +=0D + DEBUG ((DEBUG_INFO, "%a: TestMain() - Start\n", UNIT_TEST_NAME));=0D +=0D + Status =3D InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCaller= BaseName, UNIT_TEST_VERSION);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "%a: Failed in InitUnitTestFramework. Status =3D = %r\n", UNIT_TEST_NAME, Status));=0D + goto EXIT;=0D + }=0D +=0D + Status =3D CreateUnitTestSuite (&Tcg2MeasureBootLibValidationTestSuite, = Framework, "Tcg2MeasureBootLibValidationTestSuite", "Common.Tcg2MeasureBoot= LibValidation", NULL, NULL);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "%s: Failed in CreateUnitTestSuite for Tcg2Measur= eBootLibValidationTestSuite\n", UNIT_TEST_NAME));=0D + Status =3D EFI_OUT_OF_RESOURCES;=0D + goto EXIT;=0D + }=0D +=0D + // -----------Suite---------------------------------Description---------= -------------------Class----------------------------------Test Function----= --------------------Pre---Clean-Context=0D + AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Validating EF= I Partition Table", "Common.Tcg2MeasureBootLibValidation", TestSanitizeEfiP= artitionTableHeader, NULL, NULL, NULL);=0D + AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary heade= r gpt event checks for overflow", "Common.Tcg2MeasureBootLibValidation", Te= stSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL);=0D + AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary heade= r allocation size checks for overflow", "Common.Tcg2MeasureBootLibValidatio= n", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL);=0D +=0D + Status =3D RunAllTestSuites (Framework);=0D +=0D +EXIT:=0D + if (Framework !=3D NULL) {=0D + FreeUnitTestFramework (Framework);=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "%a: TestMain() - End\n", UNIT_TEST_NAME));=0D + return Status;=0D +}=0D +=0D +///=0D +/// Avoid ECC error for function name that starts with lower case letter=0D +///=0D +#define DxeTpm2MeasureBootLibUnitTestMain main=0D +=0D +/**=0D + Standard POSIX C entry point for host based unit test execution.=0D +=0D + @param[in] Argc Number of arguments=0D + @param[in] Argv Array of pointers to arguments=0D +=0D + @retval 0 Success=0D + @retval other Error=0D +**/=0D +INT32=0D +DxeTpm2MeasureBootLibUnitTestMain (=0D + IN INT32 Argc,=0D + IN CHAR8 *Argv[]=0D + )=0D +{=0D + return (INT32)UefiTestMain ();=0D +}=0D 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 @@ ## ]=0D "ExceptionList": [=0D "8005", "gRT",=0D + "8001", "DxeTpm2MeasureBootLibUnitTestMain",=0D ],=0D ## Both file path and directory path are accepted.=0D "IgnoreFiles": [=0D --=20 2.43.0 -=-=-=-=-=-=-=-=-=-=-=- 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/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-