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 B1FABD80685 for ; Fri, 12 Jan 2024 19:16:07 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=jS2CZjM5hpICa+YbOJ757OgLWa+2pmgYXOmz7I8Q4ho=; 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=1705086966; v=1; b=qvDd+/wn+U759pnckUHBvtQwJFmuc20jKx7IbYgnVWB1GJz+0m8vmMKvfIN23lW0A8W3fNe5 S4nIrQ+udGo5YqEJ0WwEBri5gPPhZN482Nzskco6ohIyonjD3qXCng2uQfBC93KIEzQXyavTsmW hZYJWm9h6OJUxWTXvffvGbhI= X-Received: by 127.0.0.2 with SMTP id J3Y0YY7687511xYhbRMuDJbV; Fri, 12 Jan 2024 11:16:06 -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: 8VmvlZLd5KTVe5LluU59QaBWx7686176AA= 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-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b="qvDd+/wn"; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io; dmarc=none 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=0D );=0D =0D +/**=0D + This function will validate that the PeImage Event Size from the loaded = image is sane=0D + It will check the following:=0D + - EventSize does not overflow=0D +=0D + @param[in] FilePathSize - Size of the file path.=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 +SanitizePeImageEventSize (=0D + IN UINT32 FilePathSize,=0D + OUT UINT32 *EventSize=0D + );=0D +=0D #endif // DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_=0D 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 @@ =0D Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
=0D SPDX-License-Identifier: BSD-2-Clause-Patent=0D +Copyright (c) Microsoft Corporation.
=0D =0D Copyright (c) Microsoft Corporation.
=0D SPDX-License-Identifier: BSD-2-Clause-Patent=0D @@ -345,18 +346,22 @@ TcgMeasurePeImage ( ImageLoad =3D NULL;=0D SectionHeader =3D NULL;=0D Sha1Ctx =3D NULL;=0D + TcgEvent =3D NULL;=0D FilePathSize =3D (UINT32)GetDevicePathSize (FilePath);=0D =0D - //=0D // Determine destination PCR by BootPolicy=0D //=0D - EventSize =3D sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + Fil= ePathSize;=0D - TcgEvent =3D AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT));=0D + Status =3D SanitizePeImageEventSize (FilePathSize, &EventSize);=0D + if (EFI_ERROR (Status)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + TcgEvent =3D AllocateZeroPool (EventSize);=0D if (TcgEvent =3D=3D NULL) {=0D return EFI_OUT_OF_RESOURCES;=0D }=0D =0D - TcgEvent->EventSize =3D EventSize;=0D + TcgEvent->EventSize =3D EventSize - sizeof (TCG_PCR_EVENT_HDR);=0D ImageLoad =3D (EFI_IMAGE_LOAD_EVENT *)TcgEvent->Event;=0D =0D switch (ImageType) {=0D 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 ( =0D return EFI_SUCCESS;=0D }=0D +=0D +/**=0D + This function will validate that the PeImage Event Size from the loaded = image is sane=0D + It will check the following:=0D + - EventSize does not overflow=0D +=0D + @param[in] FilePathSize - Size of the file path.=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 +SanitizePeImageEventSize (=0D + IN UINT32 FilePathSize,=0D + OUT UINT32 *EventSize=0D + )=0D +{=0D + EFI_STATUS Status;=0D +=0D + // Replacing logic:=0D + // sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize;= =0D + Status =3D SafeUint32Add (OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath), = FilePathSize, EventSize);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n"));=0D + return EFI_BAD_BUFFER_SIZE;=0D + }=0D +=0D + // Replacing logic:=0D + // EventSize + sizeof (TCG_PCR_EVENT_HDR)=0D + Status =3D SafeUint32Add (*EventSize, sizeof (TCG_PCR_EVENT_HDR), EventS= ize);=0D + if (EFI_ERROR (Status)) {=0D + DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n"));=0D + return EFI_BAD_BUFFER_SIZE;=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D 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=0D -This file includes the unit test cases for the DxeTpmMeasureBootLibSanitiz= ationTest.c.=0D + This file includes the unit test cases for the DxeTpmMeasureBootLibSanit= izationTest.c.=0D =0D -Copyright (c) Microsoft Corporation.
=0D -SPDX-License-Identifier: BSD-2-Clause-Patent=0D + Copyright (c) Microsoft Corporation.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D **/=0D =0D #include =0D @@ -186,9 +186,6 @@ TestSanitizePrimaryHeaderGptEventSize ( EFI_STATUS Status;=0D EFI_PARTITION_TABLE_HEADER PrimaryHeader;=0D UINTN NumberOfPartition;=0D - EFI_GPT_DATA *GptData;=0D -=0D - GptData =3D NULL;=0D =0D // Test that a normal PrimaryHeader passes validation=0D PrimaryHeader.NumberOfPartitionEntries =3D 5;=0D @@ -222,6 +219,94 @@ TestSanitizePrimaryHeaderGptEventSize ( return UNIT_TEST_PASSED;=0D }=0D =0D +/**=0D + This function tests the SanitizePeImageEventSize function.=0D + It's intent is to test that the untrusted input from a file path for an= =0D + EFI_IMAGE_LOAD_EVENT structure will not cause an overflow when calculati= ng=0D + the event size when allocating space.=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 +TestSanitizePeImageEventSize (=0D + IN UNIT_TEST_CONTEXT Context=0D + )=0D +{=0D + UINT32 EventSize;=0D + UINTN ExistingLogicEventSize;=0D + UINT32 FilePathSize;=0D + EFI_STATUS Status;=0D + EFI_DEVICE_PATH_PROTOCOL DevicePath;=0D + EFI_IMAGE_LOAD_EVENT *ImageLoadEvent;=0D + UNIT_TEST_STATUS TestStatus;=0D +=0D + TestStatus =3D UNIT_TEST_ERROR_TEST_FAILED;=0D +=0D + // Generate EFI_DEVICE_PATH_PROTOCOL test data=0D + DevicePath.Type =3D 0;=0D + DevicePath.SubType =3D 0;=0D + DevicePath.Length[0] =3D 0;=0D + DevicePath.Length[1] =3D 0;=0D +=0D + // Generate EFI_IMAGE_LOAD_EVENT test data=0D + ImageLoadEvent =3D AllocateZeroPool (sizeof (EFI_IMAGE_LOAD_EVENT) + siz= eof (EFI_DEVICE_PATH_PROTOCOL));=0D + if (ImageLoadEvent =3D=3D NULL) {=0D + DEBUG ((DEBUG_ERROR, "%a: AllocateZeroPool failed\n", __func__));=0D + goto Exit;=0D + }=0D +=0D + // Populate EFI_IMAGE_LOAD_EVENT54 test data=0D + ImageLoadEvent->ImageLocationInMemory =3D (EFI_PHYSICAL_ADDRESS)0x123456= 78;=0D + ImageLoadEvent->ImageLengthInMemory =3D 0x1000;=0D + ImageLoadEvent->ImageLinkTimeAddress =3D (UINTN)ImageLoadEvent;=0D + ImageLoadEvent->LengthOfDevicePath =3D sizeof (EFI_DEVICE_PATH_PROTOC= OL);=0D + CopyMem (ImageLoadEvent->DevicePath, &DevicePath, sizeof (EFI_DEVICE_PAT= H_PROTOCOL));=0D +=0D + FilePathSize =3D 255;=0D +=0D + // Test that a normal PE image passes validation=0D + Status =3D SanitizePeImageEventSize (FilePathSize, &EventSize);=0D + if (EFI_ERROR (Status)) {=0D + UT_LOG_ERROR ("SanitizePeImageEventSize failed with %r\n", Status);=0D + goto Exit;=0D + }=0D +=0D + // Test that the event size is correct compared to the existing logic=0D + ExistingLogicEventSize =3D OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath)= + FilePathSize;=0D + ExistingLogicEventSize +=3D sizeof (TCG_PCR_EVENT_HDR);=0D +=0D + if (EventSize !=3D ExistingLogicEventSize) {=0D + UT_LOG_ERROR ("SanitizePeImageEventSize returned an incorrect event si= ze. Expected %u, got %u\n", ExistingLogicEventSize, EventSize);=0D + goto Exit;=0D + }=0D +=0D + // Test that the event size may not overflow=0D + Status =3D SanitizePeImageEventSize (MAX_UINT32, &EventSize);=0D + if (Status !=3D EFI_BAD_BUFFER_SIZE) {=0D + UT_LOG_ERROR ("SanitizePeImageEventSize succeded when it was supposed = to fail with %r\n", Status);=0D + goto Exit;=0D + }=0D +=0D + TestStatus =3D UNIT_TEST_PASSED;=0D +Exit:=0D +=0D + if (ImageLoadEvent !=3D NULL) {=0D + FreePool (ImageLoadEvent);=0D + }=0D +=0D + if (TestStatus =3D=3D UNIT_TEST_ERROR_TEST_FAILED) {=0D + DEBUG ((DEBUG_ERROR, "%a: Test failed\n", __func__));=0D + } else {=0D + DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__));=0D + }=0D +=0D + return TestStatus;=0D +}=0D +=0D // *--------------------------------------------------------------------*= =0D // * Unit Test Code Main Function=0D // *--------------------------------------------------------------------*= =0D @@ -265,6 +350,7 @@ UefiTestMain ( AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Validating EFI= Partition Table", "Common.TcgMeasureBootLibValidation", TestSanitizeEfiPar= titionTableHeader, NULL, NULL, NULL);=0D AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header= gpt event checks for overflow", "Common.TcgMeasureBootLibValidation", Test= SanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL);=0D AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header= allocation size checks for overflow", "Common.TcgMeasureBootLibValidation"= , TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL);=0D + AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests PE Image and F= ileSize checks for overflow", "Common.TcgMeasureBootLibValidation", TestSan= itizePeImageEventSize, NULL, NULL, NULL);=0D =0D Status =3D RunAllTestSuites (Framework);=0D =0D --=20 2.43.0 -=-=-=-=-=-=-=-=-=-=-=- 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/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-