Fix some CVE
fix CVE-2022-36763、CVE-2022-36764、CVE-2022-36765 Signed-off-by: yexiao <yexiao7@huawei.com> (cherry picked from commit 45d7902c879c8a960a59b4d86c97ca7b7c1765c6)
This commit is contained in:
parent
bf93641b42
commit
33439c309c
995
0012-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch
Normal file
995
0012-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch
Normal file
@ -0,0 +1,995 @@
|
|||||||
|
From 1adc7d6bea3bcd15f8ce5040b99c12665dcb240e Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Douglas Flick [MSFT]" <doug.edk2@gmail.com>
|
||||||
|
Date: Fri, 12 Jan 2024 02:16:01 +0800
|
||||||
|
Subject: [PATCH 01/10] SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4117
|
||||||
|
- CVE 2022-36763
|
||||||
|
|
||||||
|
This commit contains the patch files and tests for DxeTpm2MeasureBootLib
|
||||||
|
CVE 2022-36763.
|
||||||
|
|
||||||
|
Cc: Jiewen Yao <jiewen.yao@intel.com>
|
||||||
|
|
||||||
|
Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
|
||||||
|
|
||||||
|
reference: https://github.com/tianocore/edk2/pull/5264
|
||||||
|
Signed-off-by: yexiao <yexiao7@huawei.com>
|
||||||
|
---
|
||||||
|
.../DxeTpm2MeasureBootLib.c | 69 ++--
|
||||||
|
.../DxeTpm2MeasureBootLib.inf | 4 +-
|
||||||
|
.../DxeTpm2MeasureBootLibSanitization.c | 275 ++++++++++++++++
|
||||||
|
.../DxeTpm2MeasureBootLibSanitization.h | 113 +++++++
|
||||||
|
.../DxeTpm2MeasureBootLibSanitizationTest.c | 303 ++++++++++++++++++
|
||||||
|
...Tpm2MeasureBootLibSanitizationTestHost.inf | 28 ++
|
||||||
|
SecurityPkg/SecurityPkg.ci.yaml | 1 +
|
||||||
|
SecurityPkg/Test/SecurityPkgHostTest.dsc | 1 +
|
||||||
|
8 files changed, 764 insertions(+), 30 deletions(-)
|
||||||
|
create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c
|
||||||
|
create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h
|
||||||
|
create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c
|
||||||
|
create mode 100644 SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf
|
||||||
|
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c
|
||||||
|
index 36a256a7..0a37a4b6 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.<BR>
|
||||||
|
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
+Copyright (c) Microsoft Corporation.<BR>
|
||||||
|
+SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <PiDxe.h>
|
||||||
|
@@ -44,6 +46,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#include <Library/HobLib.h>
|
||||||
|
#include <Protocol/CcMeasurement.h>
|
||||||
|
|
||||||
|
+#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;
|
||||||
|
|
||||||
|
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 (PrimaryHeader, BlockIo))) {
|
||||||
|
+ DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n"));
|
||||||
|
FreePool (PrimaryHeader);
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
- // PrimaryHeader->SizeOfPartitionEntry should not be zero
|
||||||
|
+ // Read the partition entry.
|
||||||
|
//
|
||||||
|
- if (PrimaryHeader->SizeOfPartitionEntry == 0) {
|
||||||
|
- DEBUG ((DEBUG_ERROR, "SizeOfPartitionEntry should not be zero!\n"));
|
||||||
|
+ Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize);
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
FreePool (PrimaryHeader);
|
||||||
|
return EFI_BAD_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
- //
|
||||||
|
- // Read the partition entry.
|
||||||
|
- //
|
||||||
|
- EntryPtr = (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry);
|
||||||
|
+ EntryPtr = (UINT8 *)AllocatePool (AllocSize);
|
||||||
|
if (EntryPtr == 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 * PrimaryHeader->SizeOfPartitionEntry,
|
||||||
|
+ AllocSize,
|
||||||
|
EntryPtr
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
@@ -248,16 +250,21 @@ Tcg2MeasureGptTable (
|
||||||
|
//
|
||||||
|
// Prepare Data for Measurement (CcProtocol and Tcg2Protocol)
|
||||||
|
//
|
||||||
|
- EventSize = (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions)
|
||||||
|
- + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry);
|
||||||
|
- EventPtr = (UINT8 *)AllocateZeroPool (EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event));
|
||||||
|
+ Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &TcgEventSize);
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ FreePool (PrimaryHeader);
|
||||||
|
+ FreePool (EntryPtr);
|
||||||
|
+ return EFI_DEVICE_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ EventPtr = (UINT8 *)AllocateZeroPool (TcgEventSize);
|
||||||
|
if (EventPtr == NULL) {
|
||||||
|
Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tcg2Event = (EFI_TCG2_EVENT *)EventPtr;
|
||||||
|
- Tcg2Event->Size = EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event);
|
||||||
|
+ Tcg2Event->Size = TcgEventSize;
|
||||||
|
Tcg2Event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER);
|
||||||
|
Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
|
||||||
|
Tcg2Event->Header.PCRIndex = 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_EVENT, Event),
|
||||||
|
Tcg2Event
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
@@ -443,11 +450,13 @@ Tcg2MeasurePeImage (
|
||||||
|
Tcg2Event->Header.PCRIndex = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
- DEBUG ((
|
||||||
|
- DEBUG_ERROR,
|
||||||
|
- "Tcg2MeasurePeImage: Unknown subsystem type %d",
|
||||||
|
- ImageType
|
||||||
|
- ));
|
||||||
|
+ DEBUG (
|
||||||
|
+ (
|
||||||
|
+ DEBUG_ERROR,
|
||||||
|
+ "Tcg2MeasurePeImage: Unknown subsystem type %d",
|
||||||
|
+ ImageType
|
||||||
|
+ )
|
||||||
|
+ );
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -515,7 +524,7 @@ Finish:
|
||||||
|
|
||||||
|
@param MeasureBootProtocols Pointer to the located measure boot protocol instances.
|
||||||
|
|
||||||
|
- @retval EFI_SUCCESS Sucessfully locate the measure boot protocol instances (at least one instance).
|
||||||
|
+ @retval EFI_SUCCESS Successfully locate the measure boot protocol instances (at least one instance).
|
||||||
|
@retval EFI_UNSUPPORTED Measure boot is not supported.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
@@ -646,12 +655,14 @@ DxeTpm2MeasureBootHandler (
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
- DEBUG ((
|
||||||
|
- DEBUG_INFO,
|
||||||
|
- "Tcg2Protocol = %p, CcMeasurementProtocol = %p\n",
|
||||||
|
- MeasureBootProtocols.Tcg2Protocol,
|
||||||
|
- MeasureBootProtocols.CcProtocol
|
||||||
|
- ));
|
||||||
|
+ DEBUG (
|
||||||
|
+ (
|
||||||
|
+ DEBUG_INFO,
|
||||||
|
+ "Tcg2Protocol = %p, CcMeasurementProtocol = %p\n",
|
||||||
|
+ MeasureBootProtocols.Tcg2Protocol,
|
||||||
|
+ MeasureBootProtocols.CcProtocol
|
||||||
|
+ )
|
||||||
|
+ );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy File Device Path
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
|
||||||
|
index 6dca79a2..78395573 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
|
||||||
|
@@ -37,6 +37,8 @@
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
DxeTpm2MeasureBootLib.c
|
||||||
|
+ DxeTpm2MeasureBootLibSanitization.c
|
||||||
|
+ DxeTpm2MeasureBootLibSanitization.h
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
@@ -46,6 +48,7 @@
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
BaseMemoryLib
|
||||||
|
+ SafeIntLib
|
||||||
|
DebugLib
|
||||||
|
MemoryAllocationLib
|
||||||
|
DevicePathLib
|
||||||
|
@@ -65,4 +68,3 @@
|
||||||
|
gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
|
gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
|
gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
|
-
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..ef3b77b4
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.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 functions, 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 image content
|
||||||
|
+ read is within the image buffer.
|
||||||
|
+
|
||||||
|
+ Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse
|
||||||
|
+ partition data carefully.
|
||||||
|
+
|
||||||
|
+ Copyright (c) Microsoft Corporation.<BR>
|
||||||
|
+ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
+**/
|
||||||
|
+#include <Uefi.h>
|
||||||
|
+#include <Uefi/UefiSpec.h>
|
||||||
|
+#include <Library/SafeIntLib.h>
|
||||||
|
+#include <Library/UefiLib.h>
|
||||||
|
+#include <Library/DebugLib.h>
|
||||||
|
+#include <Library/BaseLib.h>
|
||||||
|
+#include <IndustryStandard/UefiTcgPlatform.h>
|
||||||
|
+#include <Protocol/BlockIo.h>
|
||||||
|
+#include <Library/MemoryAllocationLib.h>
|
||||||
|
+
|
||||||
|
+#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 == NULL) {
|
||||||
|
+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n"));
|
||||||
|
+ return EFI_INVALID_PARAMETER;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((BlockIo == NULL) || (BlockIo->Media == 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 != 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 != 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 than or equal to the logical block size
|
||||||
|
+ //
|
||||||
|
+ if ((PrimaryHeader->Header.HeaderSize < sizeof (EFI_PARTITION_TABLE_HEADER)) || (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 <= PrimaryHeader->PartitionEntryLBA) {
|
||||||
|
+ DEBUG ((DEBUG_ERROR, "GPT PartitionEntryLBA is not less than FirstUsableLBA!\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->Media->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 == 0) {
|
||||||
|
+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n"));
|
||||||
|
+ return EFI_DEVICE_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ //
|
||||||
|
+ // SizeOfPartitionEntry must be 128, 256, 512... improper size may lead to accessing uninitialized memory
|
||||||
|
+ //
|
||||||
|
+ if ((PrimaryHeader->SizeOfPartitionEntry < 128) || ((PrimaryHeader->SizeOfPartitionEntry & (PrimaryHeader->SizeOfPartitionEntry - 1)) != 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, 256, 512, etc.)!\n"));
|
||||||
|
+ return EFI_DEVICE_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ //
|
||||||
|
+ // This check is to prevent overflow when calculating the allocation size for the partition entries
|
||||||
|
+ // This check will be used later for multiplication
|
||||||
|
+ //
|
||||||
|
+ if (PrimaryHeader->NumberOfPartitionEntries > DivU64x32 (MAX_UINT64, PrimaryHeader->SizeOfPartitionEntry)) {
|
||||||
|
+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n"));
|
||||||
|
+ return EFI_DEVICE_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return EFI_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ This function will validate that the allocation size from the primary header 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 == NULL) {
|
||||||
|
+ return EFI_INVALID_PARAMETER;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (AllocationSize == NULL) {
|
||||||
|
+ return EFI_INVALID_PARAMETER;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ //
|
||||||
|
+ // Replacing logic:
|
||||||
|
+ // PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry;
|
||||||
|
+ //
|
||||||
|
+ Status = SafeUint32Mult (PrimaryHeader->NumberOfPartitionEntries, PrimaryHeader->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 space, 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 structure.
|
||||||
|
+ @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 == NULL) {
|
||||||
|
+ return EFI_INVALID_PARAMETER;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (EventSize == 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 = 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) + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry);
|
||||||
|
+ //
|
||||||
|
+ Status = SafeUint32Mult (SafeNumberOfPartitions, PrimaryHeader->SizeOfPartitionEntry, 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 = 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 GPTData!\n"));
|
||||||
|
+ return EFI_BAD_BUFFER_SIZE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return EFI_SUCCESS;
|
||||||
|
+}
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..74af8c8b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h
|
||||||
|
@@ -0,0 +1,113 @@
|
||||||
|
+/** @file
|
||||||
|
+ This file includes the function prototypes for the sanitization functions.
|
||||||
|
+
|
||||||
|
+ These are those functions:
|
||||||
|
+
|
||||||
|
+ DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF image content
|
||||||
|
+ read is within the image buffer.
|
||||||
|
+
|
||||||
|
+ Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse
|
||||||
|
+ partition data carefully.
|
||||||
|
+
|
||||||
|
+ Copyright (c) Microsoft Corporation.<BR>
|
||||||
|
+ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
+
|
||||||
|
+**/
|
||||||
|
+
|
||||||
|
+#ifndef DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_
|
||||||
|
+#define DXE_TPM2_MEASURE_BOOT_LIB_SANITATION_
|
||||||
|
+
|
||||||
|
+#include <Uefi.h>
|
||||||
|
+#include <Uefi/UefiSpec.h>
|
||||||
|
+#include <Protocol/BlockIo.h>
|
||||||
|
+#include <IndustryStandard/UefiTcgPlatform.h>
|
||||||
|
+#include <Protocol/Tcg2Protocol.h>
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ 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 header 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 space, 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 structure.
|
||||||
|
+ @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/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..701d1b46
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c
|
||||||
|
@@ -0,0 +1,303 @@
|
||||||
|
+/** @file
|
||||||
|
+ This file includes the unit test cases for the DxeTpm2MeasureBootLibSanitizationTest.c.
|
||||||
|
+
|
||||||
|
+ Copyright (c) Microsoft Corporation.<BR>
|
||||||
|
+ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
+**/
|
||||||
|
+
|
||||||
|
+#include <Uefi.h>
|
||||||
|
+#include <Library/UefiLib.h>
|
||||||
|
+#include <Library/DebugLib.h>
|
||||||
|
+#include <Library/UnitTestLib.h>
|
||||||
|
+#include <Protocol/BlockIo.h>
|
||||||
|
+#include <Library/MemoryAllocationLib.h>
|
||||||
|
+#include <Library/BaseMemoryLib.h>
|
||||||
|
+#include <IndustryStandard/UefiTcgPlatform.h>
|
||||||
|
+#include <Protocol/Tcg2Protocol.h>
|
||||||
|
+
|
||||||
|
+#include "../DxeTpm2MeasureBootLibSanitization.h"
|
||||||
|
+
|
||||||
|
+#define UNIT_TEST_NAME "DxeTpm2MeasureBootLibSanitizationTest"
|
||||||
|
+#define UNIT_TEST_VERSION "1.0"
|
||||||
|
+
|
||||||
|
+#define DEFAULT_PRIMARY_TABLE_HEADER_REVISION 0x00010000
|
||||||
|
+#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 = 1;
|
||||||
|
+ BlockMedia.RemovableMedia = FALSE;
|
||||||
|
+ BlockMedia.MediaPresent = TRUE;
|
||||||
|
+ BlockMedia.LogicalPartition = FALSE;
|
||||||
|
+ BlockMedia.ReadOnly = FALSE;
|
||||||
|
+ BlockMedia.WriteCaching = FALSE;
|
||||||
|
+ BlockMedia.BlockSize = 512;
|
||||||
|
+ BlockMedia.IoAlign = 1;
|
||||||
|
+ BlockMedia.LastBlock = 0;
|
||||||
|
+
|
||||||
|
+ // Generate EFI_BLOCK_IO_PROTOCOL test data
|
||||||
|
+ BlockIo.Revision = 1;
|
||||||
|
+ BlockIo.Media = &BlockMedia;
|
||||||
|
+ BlockIo.Reset = NULL;
|
||||||
|
+ BlockIo.ReadBlocks = NULL;
|
||||||
|
+ BlockIo.WriteBlocks = NULL;
|
||||||
|
+ BlockIo.FlushBlocks = NULL;
|
||||||
|
+
|
||||||
|
+ // Geneate EFI_PARTITION_TABLE_HEADER test data
|
||||||
|
+ PrimaryHeader.Header.Signature = EFI_PTAB_HEADER_ID;
|
||||||
|
+ PrimaryHeader.Header.Revision = DEFAULT_PRIMARY_TABLE_HEADER_REVISION;
|
||||||
|
+ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER);
|
||||||
|
+ PrimaryHeader.MyLBA = 1;
|
||||||
|
+ PrimaryHeader.AlternateLBA = 2;
|
||||||
|
+ PrimaryHeader.FirstUsableLBA = 3;
|
||||||
|
+ PrimaryHeader.LastUsableLBA = 4;
|
||||||
|
+ PrimaryHeader.PartitionEntryLBA = 5;
|
||||||
|
+ PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES;
|
||||||
|
+ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY;
|
||||||
|
+ PrimaryHeader.PartitionEntryArrayCRC32 = 0; // Purposely invalid
|
||||||
|
+
|
||||||
|
+ // Calculate the CRC32 of the PrimaryHeader
|
||||||
|
+ PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize);
|
||||||
|
+
|
||||||
|
+ // Test that a normal PrimaryHeader passes validation
|
||||||
|
+ Status = 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 = 0;
|
||||||
|
+ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
+ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR);
|
||||||
|
+ PrimaryHeader.NumberOfPartitionEntries = 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 = 0;
|
||||||
|
+ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
+ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR);
|
||||||
|
+ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER);
|
||||||
|
+
|
||||||
|
+ // Test that when the SizeOfPartitionEntry is too small, the function returns 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, 512, etc.)!"
|
||||||
|
+ PrimaryHeader.SizeOfPartitionEntry = 1;
|
||||||
|
+ Status = 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_TABLE_HEADER
|
||||||
|
+ structure will not cause an overflow when calculating the allocation 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
|
||||||
|
+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 = 5;
|
||||||
|
+ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY;
|
||||||
|
+
|
||||||
|
+ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
+ UT_ASSERT_NOT_EFI_ERROR (Status);
|
||||||
|
+
|
||||||
|
+ // Test that the allocation size is correct compared to the existing logic
|
||||||
|
+ UT_ASSERT_EQUAL (AllocationSize, PrimaryHeader.NumberOfPartitionEntries * PrimaryHeader.SizeOfPartitionEntry);
|
||||||
|
+
|
||||||
|
+ // Test that an overflow is detected
|
||||||
|
+ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32;
|
||||||
|
+ PrimaryHeader.SizeOfPartitionEntry = 5;
|
||||||
|
+ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
+
|
||||||
|
+ // Test the inverse
|
||||||
|
+ PrimaryHeader.NumberOfPartitionEntries = 5;
|
||||||
|
+ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32;
|
||||||
|
+ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
+
|
||||||
|
+ // Test the worst case scenario
|
||||||
|
+ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32;
|
||||||
|
+ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32;
|
||||||
|
+ Status = SanitizePrimaryHeaderAllocationSize (&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 structure
|
||||||
|
+ 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 = NULL;
|
||||||
|
+ GptData = NULL;
|
||||||
|
+
|
||||||
|
+ // Test that a normal PrimaryHeader passes validation
|
||||||
|
+ PrimaryHeader.NumberOfPartitionEntries = 5;
|
||||||
|
+ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY;
|
||||||
|
+
|
||||||
|
+ // set the number of partitions
|
||||||
|
+ NumberOfPartition = 13;
|
||||||
|
+
|
||||||
|
+ // that the primary event size is correct
|
||||||
|
+ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize);
|
||||||
|
+ UT_ASSERT_NOT_EFI_ERROR (Status);
|
||||||
|
+
|
||||||
|
+ // Calculate the existing logic event size
|
||||||
|
+ ExistingLogicEventSize = (UINT32)(OFFSET_OF (EFI_TCG2_EVENT, Event) + OFFSET_OF (EFI_GPT_DATA, Partitions)
|
||||||
|
+ + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry);
|
||||||
|
+
|
||||||
|
+ // Check that the event size is correct
|
||||||
|
+ UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize);
|
||||||
|
+
|
||||||
|
+ // Tests that the primary event size may not overflow
|
||||||
|
+ Status = 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 = MAX_UINT32;
|
||||||
|
+ Status = 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 = NULL;
|
||||||
|
+
|
||||||
|
+ DEBUG ((DEBUG_INFO, "%a: TestMain() - Start\n", UNIT_TEST_NAME));
|
||||||
|
+
|
||||||
|
+ Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION);
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ DEBUG ((DEBUG_ERROR, "%a: Failed in InitUnitTestFramework. Status = %r\n", UNIT_TEST_NAME, Status));
|
||||||
|
+ goto EXIT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ Status = CreateUnitTestSuite (&Tcg2MeasureBootLibValidationTestSuite, Framework, "Tcg2MeasureBootLibValidationTestSuite", "Common.Tcg2MeasureBootLibValidation", NULL, NULL);
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ DEBUG ((DEBUG_ERROR, "%s: Failed in CreateUnitTestSuite for Tcg2MeasureBootLibValidationTestSuite\n", UNIT_TEST_NAME));
|
||||||
|
+ Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
+ goto EXIT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // -----------Suite---------------------------------Description----------------------------Class----------------------------------Test Function------------------------Pre---Clean-Context
|
||||||
|
+ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Validating EFI Partition Table", "Common.Tcg2MeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL);
|
||||||
|
+ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL);
|
||||||
|
+ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL);
|
||||||
|
+
|
||||||
|
+ Status = RunAllTestSuites (Framework);
|
||||||
|
+
|
||||||
|
+EXIT:
|
||||||
|
+ if (Framework != 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/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..4ea55787
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf
|
||||||
|
@@ -0,0 +1,28 @@
|
||||||
|
+## @file
|
||||||
|
+# This file builds the unit tests for DxeTpm2MeasureBootLib
|
||||||
|
+#
|
||||||
|
+# Copyright (C) Microsoft Corporation.<BR>
|
||||||
|
+# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
+##
|
||||||
|
+
|
||||||
|
+[Defines]
|
||||||
|
+ INF_VERSION = 0x00010006
|
||||||
|
+ BASE_NAME = DxeTpm2MeasuredBootLibTest
|
||||||
|
+ FILE_GUID = 144d757f-d423-484e-9309-a23695fad5bd
|
||||||
|
+ MODULE_TYPE = HOST_APPLICATION
|
||||||
|
+ VERSION_STRING = 1.0
|
||||||
|
+ ENTRY_POINT = main
|
||||||
|
+
|
||||||
|
+[Sources]
|
||||||
|
+ DxeTpm2MeasureBootLibSanitizationTest.c
|
||||||
|
+ ../DxeTpm2MeasureBootLibSanitization.c
|
||||||
|
+
|
||||||
|
+[Packages]
|
||||||
|
+ MdePkg/MdePkg.dec
|
||||||
|
+
|
||||||
|
+[LibraryClasses]
|
||||||
|
+ BaseLib
|
||||||
|
+ DebugLib
|
||||||
|
+ UnitTestLib
|
||||||
|
+ PrintLib
|
||||||
|
+ SafeIntLib
|
||||||
|
diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.yaml
|
||||||
|
index 2138b0a5..97137406 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": [
|
||||||
|
diff --git a/SecurityPkg/Test/SecurityPkgHostTest.dsc b/SecurityPkg/Test/SecurityPkgHostTest.dsc
|
||||||
|
index ad5b4fc3..57ab3af0 100644
|
||||||
|
--- a/SecurityPkg/Test/SecurityPkgHostTest.dsc
|
||||||
|
+++ b/SecurityPkg/Test/SecurityPkgHostTest.dsc
|
||||||
|
@@ -26,6 +26,7 @@
|
||||||
|
SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockPlatformPKProtectionLib.inf
|
||||||
|
SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
|
||||||
|
SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.inf
|
||||||
|
+ SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build SecurityPkg HOST_APPLICATION Tests
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
899
0013-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch
Normal file
899
0013-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch
Normal file
@ -0,0 +1,899 @@
|
|||||||
|
From 2918cc8f6e594b7afc5c0304f7da057c69b08528 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Douglas Flick [MSFT]" <doug.edk2@gmail.com>
|
||||||
|
Date: Fri, 12 Jan 2024 02:16:02 +0800
|
||||||
|
Subject: [PATCH 02/10] SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4117
|
||||||
|
- CVE 2022-36763
|
||||||
|
|
||||||
|
This commit contains the patch files and tests for DxeTpmMeasureBootLib
|
||||||
|
CVE 2022-36763.
|
||||||
|
|
||||||
|
Cc: Jiewen Yao <jiewen.yao@intel.com>
|
||||||
|
|
||||||
|
Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
|
||||||
|
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
|
||||||
|
|
||||||
|
reference: https://github.com/tianocore/edk2/pull/5264
|
||||||
|
Signed-off-by: yexiao <yexiao7@huawei.com>
|
||||||
|
---
|
||||||
|
.../DxeTpmMeasureBootLib.c | 40 ++-
|
||||||
|
.../DxeTpmMeasureBootLib.inf | 4 +-
|
||||||
|
.../DxeTpmMeasureBootLibSanitization.c | 241 ++++++++++++++
|
||||||
|
.../DxeTpmMeasureBootLibSanitization.h | 114 +++++++
|
||||||
|
.../DxeTpmMeasureBootLibSanitizationTest.c | 301 ++++++++++++++++++
|
||||||
|
...eTpmMeasureBootLibSanitizationTestHost.inf | 28 ++
|
||||||
|
SecurityPkg/SecurityPkg.ci.yaml | 1 +
|
||||||
|
SecurityPkg/Test/SecurityPkgHostTest.dsc | 1 +
|
||||||
|
8 files changed, 716 insertions(+), 14 deletions(-)
|
||||||
|
create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c
|
||||||
|
create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h
|
||||||
|
create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c
|
||||||
|
create mode 100644 SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf
|
||||||
|
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
|
||||||
|
index 220393dd..f31b49f8 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.<BR>
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
+Copyright (c) Microsoft Corporation.<BR>
|
||||||
|
+SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <PiDxe.h>
|
||||||
|
@@ -40,6 +42,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#include <Library/SecurityManagementLib.h>
|
||||||
|
#include <Library/HobLib.h>
|
||||||
|
|
||||||
|
+#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 = NULL;
|
||||||
|
|
||||||
|
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 (PrimaryHeader, 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 = (UINT8 *)AllocatePool (PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry);
|
||||||
|
+ Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize);
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ FreePool (PrimaryHeader);
|
||||||
|
+ return EFI_DEVICE_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ EntryPtr = (UINT8 *)AllocatePool (AllocSize);
|
||||||
|
if (EntryPtr == 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 * PrimaryHeader->SizeOfPartitionEntry,
|
||||||
|
+ AllocSize,
|
||||||
|
EntryPtr
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
@@ -210,9 +223,8 @@ TcgMeasureGptTable (
|
||||||
|
//
|
||||||
|
// Prepare Data for Measurement
|
||||||
|
//
|
||||||
|
- EventSize = (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions)
|
||||||
|
- + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry);
|
||||||
|
- TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT_HDR));
|
||||||
|
+ Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &EventSize);
|
||||||
|
+ TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (EventSize);
|
||||||
|
if (TcgEvent == NULL) {
|
||||||
|
FreePool (PrimaryHeader);
|
||||||
|
FreePool (EntryPtr);
|
||||||
|
@@ -221,7 +233,7 @@ TcgMeasureGptTable (
|
||||||
|
|
||||||
|
TcgEvent->PCRIndex = 5;
|
||||||
|
TcgEvent->EventType = EV_EFI_GPT_EVENT;
|
||||||
|
- TcgEvent->EventSize = EventSize;
|
||||||
|
+ TcgEvent->EventSize = EventSize - sizeof (TCG_PCR_EVENT_HDR);
|
||||||
|
GptData = (EFI_GPT_DATA *)TcgEvent->Event;
|
||||||
|
|
||||||
|
//
|
||||||
|
@@ -361,11 +373,13 @@ TcgMeasurePeImage (
|
||||||
|
TcgEvent->PCRIndex = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
- DEBUG ((
|
||||||
|
- DEBUG_ERROR,
|
||||||
|
- "TcgMeasurePeImage: Unknown subsystem type %d",
|
||||||
|
- ImageType
|
||||||
|
- ));
|
||||||
|
+ DEBUG (
|
||||||
|
+ (
|
||||||
|
+ DEBUG_ERROR,
|
||||||
|
+ "TcgMeasurePeImage: Unknown subsystem type %d",
|
||||||
|
+ ImageType
|
||||||
|
+ )
|
||||||
|
+ );
|
||||||
|
goto Finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf
|
||||||
|
index ebab6f7c..21bfd570 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf
|
||||||
|
@@ -32,6 +32,8 @@
|
||||||
|
|
||||||
|
[Sources]
|
||||||
|
DxeTpmMeasureBootLib.c
|
||||||
|
+ DxeTpmMeasureBootLibSanitization.c
|
||||||
|
+ DxeTpmMeasureBootLibSanitization.h
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
@@ -41,6 +43,7 @@
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
BaseMemoryLib
|
||||||
|
+ SafeIntLib
|
||||||
|
DebugLib
|
||||||
|
MemoryAllocationLib
|
||||||
|
DevicePathLib
|
||||||
|
@@ -59,4 +62,3 @@
|
||||||
|
gEfiFirmwareVolumeBlockProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
|
gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
|
gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES
|
||||||
|
-
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..e009ce46
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.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 functions, 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 image content
|
||||||
|
+ read is within the image buffer.
|
||||||
|
+
|
||||||
|
+ Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse
|
||||||
|
+ partition data carefully.
|
||||||
|
+
|
||||||
|
+ Copyright (c) Microsoft Corporation.<BR>
|
||||||
|
+ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
+**/
|
||||||
|
+#include <Uefi.h>
|
||||||
|
+#include <Uefi/UefiSpec.h>
|
||||||
|
+#include <Library/SafeIntLib.h>
|
||||||
|
+#include <Library/UefiLib.h>
|
||||||
|
+#include <Library/DebugLib.h>
|
||||||
|
+#include <Library/BaseLib.h>
|
||||||
|
+#include <IndustryStandard/UefiTcgPlatform.h>
|
||||||
|
+#include <Protocol/BlockIo.h>
|
||||||
|
+#include <Library/MemoryAllocationLib.h>
|
||||||
|
+
|
||||||
|
+#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 == NULL) {
|
||||||
|
+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n"));
|
||||||
|
+ return EFI_INVALID_PARAMETER;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((BlockIo == NULL) || (BlockIo->Media == 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 != 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 != 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 than or equal to the logical block size
|
||||||
|
+ if ((PrimaryHeader->Header.HeaderSize < sizeof (EFI_PARTITION_TABLE_HEADER)) || (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->Media->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 == 0) {
|
||||||
|
+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n"));
|
||||||
|
+ return EFI_DEVICE_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // SizeOfPartitionEntry must be 128, 256, 512... improper size may lead to accessing uninitialized memory
|
||||||
|
+ if ((PrimaryHeader->SizeOfPartitionEntry < 128) || ((PrimaryHeader->SizeOfPartitionEntry & (PrimaryHeader->SizeOfPartitionEntry - 1)) != 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, 256, 512, etc.)!\n"));
|
||||||
|
+ return EFI_DEVICE_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // This check is to prevent overflow when calculating the allocation size for the partition entries
|
||||||
|
+ // This check will be used later for multiplication
|
||||||
|
+ if (PrimaryHeader->NumberOfPartitionEntries > DivU64x32 (MAX_UINT64, PrimaryHeader->SizeOfPartitionEntry)) {
|
||||||
|
+ DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n"));
|
||||||
|
+ return EFI_DEVICE_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return EFI_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ This function will validate that the allocation size from the primary header 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 == NULL) {
|
||||||
|
+ return EFI_INVALID_PARAMETER;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (AllocationSize == NULL) {
|
||||||
|
+ return EFI_INVALID_PARAMETER;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Replacing logic:
|
||||||
|
+ // PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry;
|
||||||
|
+ Status = SafeUint32Mult (PrimaryHeader->NumberOfPartitionEntries, PrimaryHeader->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 space, 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 hashing.
|
||||||
|
+
|
||||||
|
+ @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER structure.
|
||||||
|
+ @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 == NULL) {
|
||||||
|
+ return EFI_INVALID_PARAMETER;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (EventSize == 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 = 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) + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry + sizeof (TCG_PCR_EVENT_HDR));
|
||||||
|
+ Status = SafeUint32Mult (SafeNumberOfPartitions, PrimaryHeader->SizeOfPartitionEntry, EventSize);
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ DEBUG ((DEBUG_ERROR, "Event Size would have overflowed!\n"));
|
||||||
|
+ return EFI_BAD_BUFFER_SIZE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ Status = 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 GPTData!\n"));
|
||||||
|
+ return EFI_BAD_BUFFER_SIZE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return EFI_SUCCESS;
|
||||||
|
+}
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..57e05e48
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h
|
||||||
|
@@ -0,0 +1,114 @@
|
||||||
|
+/** @file
|
||||||
|
+ This file includes the function prototypes for the sanitization functions.
|
||||||
|
+
|
||||||
|
+ These are those functions:
|
||||||
|
+
|
||||||
|
+ DxeTpmMeasureBootLibImageRead() function will make sure the PE/COFF image content
|
||||||
|
+ read is within the image buffer.
|
||||||
|
+
|
||||||
|
+ TcgMeasurePeImage() function will accept untrusted PE/COFF image and validate 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.<BR>
|
||||||
|
+ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
+
|
||||||
|
+**/
|
||||||
|
+
|
||||||
|
+#ifndef DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_
|
||||||
|
+#define DXE_TPM_MEASURE_BOOT_LIB_VALIDATION_
|
||||||
|
+
|
||||||
|
+#include <Uefi.h>
|
||||||
|
+#include <Uefi/UefiSpec.h>
|
||||||
|
+#include <Protocol/BlockIo.h>
|
||||||
|
+#include <IndustryStandard/UefiTcgPlatform.h>
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ 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 header 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 space, 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 hashing.
|
||||||
|
+
|
||||||
|
+ @param[in] PrimaryHeader - Pointer to the EFI_PARTITION_TABLE_HEADER structure.
|
||||||
|
+ @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/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..8cd97480
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c
|
||||||
|
@@ -0,0 +1,301 @@
|
||||||
|
+/** @file
|
||||||
|
+This file includes the unit test cases for the DxeTpmMeasureBootLibSanitizationTest.c.
|
||||||
|
+
|
||||||
|
+Copyright (c) Microsoft Corporation.<BR>
|
||||||
|
+SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
+**/
|
||||||
|
+
|
||||||
|
+#include <Uefi.h>
|
||||||
|
+#include <Library/UefiLib.h>
|
||||||
|
+#include <Library/DebugLib.h>
|
||||||
|
+#include <Library/UnitTestLib.h>
|
||||||
|
+#include <Protocol/BlockIo.h>
|
||||||
|
+#include <Library/MemoryAllocationLib.h>
|
||||||
|
+#include <Library/BaseMemoryLib.h>
|
||||||
|
+#include <IndustryStandard/UefiTcgPlatform.h>
|
||||||
|
+
|
||||||
|
+#include "../DxeTpmMeasureBootLibSanitization.h"
|
||||||
|
+
|
||||||
|
+#define UNIT_TEST_NAME "DxeTpmMeasureBootLibSanitizationTest"
|
||||||
|
+#define UNIT_TEST_VERSION "1.0"
|
||||||
|
+
|
||||||
|
+#define DEFAULT_PRIMARY_TABLE_HEADER_REVISION 0x00010000
|
||||||
|
+#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 = 1;
|
||||||
|
+ BlockMedia.RemovableMedia = FALSE;
|
||||||
|
+ BlockMedia.MediaPresent = TRUE;
|
||||||
|
+ BlockMedia.LogicalPartition = FALSE;
|
||||||
|
+ BlockMedia.ReadOnly = FALSE;
|
||||||
|
+ BlockMedia.WriteCaching = FALSE;
|
||||||
|
+ BlockMedia.BlockSize = 512;
|
||||||
|
+ BlockMedia.IoAlign = 1;
|
||||||
|
+ BlockMedia.LastBlock = 0;
|
||||||
|
+
|
||||||
|
+ // Generate EFI_BLOCK_IO_PROTOCOL test data
|
||||||
|
+ BlockIo.Revision = 1;
|
||||||
|
+ BlockIo.Media = &BlockMedia;
|
||||||
|
+ BlockIo.Reset = NULL;
|
||||||
|
+ BlockIo.ReadBlocks = NULL;
|
||||||
|
+ BlockIo.WriteBlocks = NULL;
|
||||||
|
+ BlockIo.FlushBlocks = NULL;
|
||||||
|
+
|
||||||
|
+ // Geneate EFI_PARTITION_TABLE_HEADER test data
|
||||||
|
+ PrimaryHeader.Header.Signature = EFI_PTAB_HEADER_ID;
|
||||||
|
+ PrimaryHeader.Header.Revision = DEFAULT_PRIMARY_TABLE_HEADER_REVISION;
|
||||||
|
+ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER);
|
||||||
|
+ PrimaryHeader.MyLBA = 1;
|
||||||
|
+ PrimaryHeader.AlternateLBA = 2;
|
||||||
|
+ PrimaryHeader.FirstUsableLBA = 3;
|
||||||
|
+ PrimaryHeader.LastUsableLBA = 4;
|
||||||
|
+ PrimaryHeader.PartitionEntryLBA = 5;
|
||||||
|
+ PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES;
|
||||||
|
+ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY;
|
||||||
|
+ PrimaryHeader.PartitionEntryArrayCRC32 = 0; // Purposely invalid
|
||||||
|
+
|
||||||
|
+ // Calculate the CRC32 of the PrimaryHeader
|
||||||
|
+ PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize);
|
||||||
|
+
|
||||||
|
+ // Test that a normal PrimaryHeader passes validation
|
||||||
|
+ Status = 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 = 0;
|
||||||
|
+ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
+ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR);
|
||||||
|
+ PrimaryHeader.NumberOfPartitionEntries = 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 = 0;
|
||||||
|
+ Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
+ UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR);
|
||||||
|
+ PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER);
|
||||||
|
+
|
||||||
|
+ // Test that when the SizeOfPartitionEntry is too small, the function returns 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, 512, etc.)!"
|
||||||
|
+ PrimaryHeader.SizeOfPartitionEntry = 1;
|
||||||
|
+ Status = 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_TABLE_HEADER
|
||||||
|
+ structure will not cause an overflow when calculating the allocation 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
|
||||||
|
+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 = 5;
|
||||||
|
+ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY;
|
||||||
|
+
|
||||||
|
+ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
+ UT_ASSERT_NOT_EFI_ERROR (Status);
|
||||||
|
+
|
||||||
|
+ // Test that the allocation size is correct compared to the existing logic
|
||||||
|
+ UT_ASSERT_EQUAL (AllocationSize, PrimaryHeader.NumberOfPartitionEntries * PrimaryHeader.SizeOfPartitionEntry);
|
||||||
|
+
|
||||||
|
+ // Test that an overflow is detected
|
||||||
|
+ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32;
|
||||||
|
+ PrimaryHeader.SizeOfPartitionEntry = 5;
|
||||||
|
+ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
+
|
||||||
|
+ // Test the inverse
|
||||||
|
+ PrimaryHeader.NumberOfPartitionEntries = 5;
|
||||||
|
+ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32;
|
||||||
|
+ Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
+ UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
+
|
||||||
|
+ // Test the worst case scenario
|
||||||
|
+ PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32;
|
||||||
|
+ PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32;
|
||||||
|
+ Status = SanitizePrimaryHeaderAllocationSize (&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 structure
|
||||||
|
+ 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 = NULL;
|
||||||
|
+
|
||||||
|
+ // Test that a normal PrimaryHeader passes validation
|
||||||
|
+ PrimaryHeader.NumberOfPartitionEntries = 5;
|
||||||
|
+ PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY;
|
||||||
|
+
|
||||||
|
+ // set the number of partitions
|
||||||
|
+ NumberOfPartition = 13;
|
||||||
|
+
|
||||||
|
+ // that the primary event size is correct
|
||||||
|
+ Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize);
|
||||||
|
+ UT_ASSERT_NOT_EFI_ERROR (Status);
|
||||||
|
+
|
||||||
|
+ // Calculate the existing logic event size
|
||||||
|
+ ExistingLogicEventSize = (UINT32)(sizeof (TCG_PCR_EVENT_HDR) + OFFSET_OF (EFI_GPT_DATA, Partitions)
|
||||||
|
+ + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry);
|
||||||
|
+
|
||||||
|
+ // Check that the event size is correct
|
||||||
|
+ UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize);
|
||||||
|
+
|
||||||
|
+ // Tests that the primary event size may not overflow
|
||||||
|
+ Status = 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 = MAX_UINT32;
|
||||||
|
+ Status = 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 = NULL;
|
||||||
|
+
|
||||||
|
+ DEBUG ((DEBUG_INFO, "%a: TestMain() - Start\n", UNIT_TEST_NAME));
|
||||||
|
+
|
||||||
|
+ Status = InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCallerBaseName, UNIT_TEST_VERSION);
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ DEBUG ((DEBUG_ERROR, "%a: Failed in InitUnitTestFramework. Status = %r\n", UNIT_TEST_NAME, Status));
|
||||||
|
+ goto EXIT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ Status = CreateUnitTestSuite (&TcgMeasureBootLibValidationTestSuite, Framework, "TcgMeasureBootLibValidationTestSuite", "Common.TcgMeasureBootLibValidation", NULL, NULL);
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ DEBUG ((DEBUG_ERROR, "%s: Failed in CreateUnitTestSuite for TcgMeasureBootLibValidationTestSuite\n", UNIT_TEST_NAME));
|
||||||
|
+ Status = EFI_OUT_OF_RESOURCES;
|
||||||
|
+ goto EXIT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // -----------Suite---------------------------------Description----------------------------Class----------------------------------Test Function------------------------Pre---Clean-Context
|
||||||
|
+ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Validating EFI Partition Table", "Common.TcgMeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL);
|
||||||
|
+ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL);
|
||||||
|
+ AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL);
|
||||||
|
+
|
||||||
|
+ Status = RunAllTestSuites (Framework);
|
||||||
|
+
|
||||||
|
+EXIT:
|
||||||
|
+ if (Framework != 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/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..ba4c58cb
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf
|
||||||
|
@@ -0,0 +1,28 @@
|
||||||
|
+## @file
|
||||||
|
+# This file builds the unit tests for DxeTpmMeasureBootLib
|
||||||
|
+#
|
||||||
|
+# Copyright (C) Microsoft Corporation.<BR>
|
||||||
|
+# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
+##
|
||||||
|
+
|
||||||
|
+[Defines]
|
||||||
|
+ INF_VERSION = 0x00010006
|
||||||
|
+ BASE_NAME = DxeTpmMeasuredBootLibTest
|
||||||
|
+ FILE_GUID = eb01bc38-309c-4d3e-967e-9f078c90772f
|
||||||
|
+ MODULE_TYPE = HOST_APPLICATION
|
||||||
|
+ VERSION_STRING = 1.0
|
||||||
|
+ ENTRY_POINT = main
|
||||||
|
+
|
||||||
|
+[Sources]
|
||||||
|
+ DxeTpmMeasureBootLibSanitizationTest.c
|
||||||
|
+ ../DxeTpmMeasureBootLibSanitization.c
|
||||||
|
+
|
||||||
|
+[Packages]
|
||||||
|
+ MdePkg/MdePkg.dec
|
||||||
|
+
|
||||||
|
+[LibraryClasses]
|
||||||
|
+ BaseLib
|
||||||
|
+ DebugLib
|
||||||
|
+ UnitTestLib
|
||||||
|
+ PrintLib
|
||||||
|
+ SafeIntLib
|
||||||
|
diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.yaml
|
||||||
|
index 97137406..c6716cb1 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": [
|
||||||
|
diff --git a/SecurityPkg/Test/SecurityPkgHostTest.dsc b/SecurityPkg/Test/SecurityPkgHostTest.dsc
|
||||||
|
index 57ab3af0..470bba07 100644
|
||||||
|
--- a/SecurityPkg/Test/SecurityPkgHostTest.dsc
|
||||||
|
+++ b/SecurityPkg/Test/SecurityPkgHostTest.dsc
|
||||||
|
@@ -27,6 +27,7 @@
|
||||||
|
SecurityPkg/Library/SecureBootVariableLib/UnitTest/MockUefiLib.inf
|
||||||
|
SecurityPkg/Test/Mock/Library/GoogleTest/MockPlatformPKProtectionLib/MockPlatformPKProtectionLib.inf
|
||||||
|
SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTestHost.inf
|
||||||
|
+ SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTestHost.inf
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build SecurityPkg HOST_APPLICATION Tests
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
From 44c29a76c7bba325ba55b41811e5bbe22d1552a7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Douglas Flick [MSFT]" <doug.edk2@gmail.com>
|
||||||
|
Date: Fri, 12 Jan 2024 02:16:03 +0800
|
||||||
|
Subject: [PATCH 03/10] SecurityPkg: : Adding CVE 2022-36763 to
|
||||||
|
SecurityFixes.yaml
|
||||||
|
|
||||||
|
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 <jiewen.yao@intel.com>
|
||||||
|
|
||||||
|
Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
|
||||||
|
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
|
||||||
|
|
||||||
|
reference: https://github.com/tianocore/edk2/pull/5264
|
||||||
|
Signed-off-by: yexiao <yexiao7@huawei.com>
|
||||||
|
---
|
||||||
|
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 00000000..36ac267e
|
||||||
|
--- /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-36763"
|
||||||
|
+ - "SecurityPkg: DxeTpmMeasurement: SECURITY PATCH 4117 - CVE 2022-36763"
|
||||||
|
+ - "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 Tcg2MeasureGptTable()
|
||||||
|
+ 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=4117
|
||||||
|
+ - https://bugzilla.tianocore.org/show_bug.cgi?id=2168
|
||||||
|
+ - https://bugzilla.tianocore.org/show_bug.cgi?id=1990
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
268
0015-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch
Normal file
268
0015-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
From 820c5c78a73729f720c76345f185ca46e190cf02 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Douglas Flick [MSFT]" <doug.edk2@gmail.com>
|
||||||
|
Date: Fri, 12 Jan 2024 02:16:04 +0800
|
||||||
|
Subject: [PATCH 04/10] SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH 4118
|
||||||
|
- CVE 2022-36764
|
||||||
|
|
||||||
|
This commit contains the patch files and tests for DxeTpm2MeasureBootLib
|
||||||
|
CVE 2022-36764.
|
||||||
|
|
||||||
|
Cc: Jiewen Yao <jiewen.yao@intel.com>
|
||||||
|
|
||||||
|
Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
|
||||||
|
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
|
||||||
|
|
||||||
|
reference: https://github.com/tianocore/edk2/pull/5264
|
||||||
|
Signed-off-by: yexiao <yexiao7@huawei.com>
|
||||||
|
---
|
||||||
|
.../DxeTpm2MeasureBootLib.c | 12 ++--
|
||||||
|
.../DxeTpm2MeasureBootLibSanitization.c | 46 +++++++++++++-
|
||||||
|
.../DxeTpm2MeasureBootLibSanitization.h | 28 ++++++++-
|
||||||
|
.../DxeTpm2MeasureBootLibSanitizationTest.c | 60 ++++++++++++++++---
|
||||||
|
4 files changed, 131 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c
|
||||||
|
index 0a37a4b6..ffab7968 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 mal-format.
|
||||||
|
@retval other error value
|
||||||
|
-
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
@@ -405,6 +404,7 @@ Tcg2MeasurePeImage (
|
||||||
|
Status = EFI_UNSUPPORTED;
|
||||||
|
ImageLoad = NULL;
|
||||||
|
EventPtr = NULL;
|
||||||
|
+ Tcg2Event = NULL;
|
||||||
|
|
||||||
|
Tcg2Protocol = MeasureBootProtocols->Tcg2Protocol;
|
||||||
|
CcProtocol = MeasureBootProtocols->CcProtocol;
|
||||||
|
@@ -420,18 +420,22 @@ Tcg2MeasurePeImage (
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePathSize = (UINT32)GetDevicePathSize (FilePath);
|
||||||
|
+ Status = SanitizePeImageEventSize (FilePathSize, &EventSize);
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ return EFI_UNSUPPORTED;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine destination PCR by BootPolicy
|
||||||
|
//
|
||||||
|
- EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize;
|
||||||
|
- EventPtr = AllocateZeroPool (EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event));
|
||||||
|
+ // from a malicious GPT disk partition
|
||||||
|
+ EventPtr = AllocateZeroPool (EventSize);
|
||||||
|
if (EventPtr == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tcg2Event = (EFI_TCG2_EVENT *)EventPtr;
|
||||||
|
- Tcg2Event->Size = EventSize + sizeof (EFI_TCG2_EVENT) - sizeof (Tcg2Event->Event);
|
||||||
|
+ Tcg2Event->Size = EventSize;
|
||||||
|
Tcg2Event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER);
|
||||||
|
Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
|
||||||
|
ImageLoad = (EFI_IMAGE_LOAD_EVENT *)Tcg2Event->Event;
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c
|
||||||
|
index ef3b77b4..bc583c97 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c
|
||||||
|
@@ -151,7 +151,7 @@ SanitizeEfiPartitionTableHeader (
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
- This function will validate that the allocation size from the primary header is sane
|
||||||
|
+ This function will validate that the allocation size from the primary header is sane
|
||||||
|
It will check the following:
|
||||||
|
- AllocationSize does not overflow
|
||||||
|
|
||||||
|
@@ -273,3 +273,47 @@ SanitizePrimaryHeaderGptEventSize (
|
||||||
|
|
||||||
|
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 = 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 = 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/DxeTpm2MeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h
|
||||||
|
index 74af8c8b..bfbfb589 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h
|
||||||
|
@@ -9,6 +9,9 @@
|
||||||
|
Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse
|
||||||
|
partition data carefully.
|
||||||
|
|
||||||
|
+ Tcg2MeasurePeImage() function will accept untrusted PE/COFF image and validate its
|
||||||
|
+ data structure within this image buffer before use.
|
||||||
|
+
|
||||||
|
Copyright (c) Microsoft Corporation.<BR>
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
@@ -110,4 +113,27 @@ SanitizePrimaryHeaderGptEventSize (
|
||||||
|
OUT UINT32 *EventSize
|
||||||
|
);
|
||||||
|
|
||||||
|
-#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/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c
|
||||||
|
index 701d1b46..8d8c0b26 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c
|
||||||
|
@@ -72,10 +72,10 @@ TestSanitizeEfiPartitionTableHeader (
|
||||||
|
PrimaryHeader.Header.Revision = DEFAULT_PRIMARY_TABLE_HEADER_REVISION;
|
||||||
|
PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER);
|
||||||
|
PrimaryHeader.MyLBA = 1;
|
||||||
|
- PrimaryHeader.AlternateLBA = 2;
|
||||||
|
- PrimaryHeader.FirstUsableLBA = 3;
|
||||||
|
- PrimaryHeader.LastUsableLBA = 4;
|
||||||
|
- PrimaryHeader.PartitionEntryLBA = 5;
|
||||||
|
+ PrimaryHeader.PartitionEntryLBA = 2;
|
||||||
|
+ PrimaryHeader.AlternateLBA = 3;
|
||||||
|
+ PrimaryHeader.FirstUsableLBA = 4;
|
||||||
|
+ PrimaryHeader.LastUsableLBA = 5;
|
||||||
|
PrimaryHeader.NumberOfPartitionEntries = DEFAULT_PRIMARY_TABLE_HEADER_NUMBER_OF_PARTITION_ENTRIES;
|
||||||
|
PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY;
|
||||||
|
PrimaryHeader.PartitionEntryArrayCRC32 = 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 = NULL;
|
||||||
|
- GptData = NULL;
|
||||||
|
|
||||||
|
// Test that a normal PrimaryHeader passes validation
|
||||||
|
PrimaryHeader.NumberOfPartitionEntries = 5;
|
||||||
|
@@ -225,6 +220,52 @@ TestSanitizePrimaryHeaderGptEventSize (
|
||||||
|
return UNIT_TEST_PASSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ This function tests the SanitizePeImageEventSize function.
|
||||||
|
+ It's intent is to test that the untrusted input from a file path when generating a
|
||||||
|
+ EFI_IMAGE_LOAD_EVENT structure will not cause an overflow when calculating
|
||||||
|
+ 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 = 255;
|
||||||
|
+
|
||||||
|
+ // Test that a normal PE image passes validation
|
||||||
|
+ Status = SanitizePeImageEventSize (FilePathSize, &EventSize);
|
||||||
|
+ UT_ASSERT_EQUAL (Status, EFI_SUCCESS);
|
||||||
|
+
|
||||||
|
+ // Test that the event size is correct compared to the existing logic
|
||||||
|
+ ExistingLogicEventSize = OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath) + FilePathSize;
|
||||||
|
+ ExistingLogicEventSize += OFFSET_OF (EFI_TCG2_EVENT, Event);
|
||||||
|
+
|
||||||
|
+ if (EventSize != ExistingLogicEventSize) {
|
||||||
|
+ UT_LOG_ERROR ("SanitizePeImageEventSize returned an incorrect event size. Expected %u, got %u\n", ExistingLogicEventSize, EventSize);
|
||||||
|
+ return UNIT_TEST_ERROR_TEST_FAILED;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Test that the event size may not overflow
|
||||||
|
+ Status = 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 EFI Partition Table", "Common.Tcg2MeasureBootLibValidation", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL);
|
||||||
|
AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, NULL, NULL, NULL);
|
||||||
|
AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests Primary header allocation size checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePrimaryHeaderGptEventSize, NULL, NULL, NULL);
|
||||||
|
+ AddTestCase (Tcg2MeasureBootLibValidationTestSuite, "Tests PE Image and FileSize checks for overflow", "Common.Tcg2MeasureBootLibValidation", TestSanitizePeImageEventSize, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
Status = RunAllTestSuites (Framework);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
278
0016-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4118.patch
Normal file
278
0016-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4118.patch
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
From 22690cad49ef3b07c2bba554eabbf9e1b631f55c Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Douglas Flick [MSFT]" <doug.edk2@gmail.com>
|
||||||
|
Date: Fri, 12 Jan 2024 02:16:05 +0800
|
||||||
|
Subject: [PATCH 05/10] SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH 4118
|
||||||
|
- CVE 2022-36764
|
||||||
|
|
||||||
|
This commit contains the patch files and tests for DxeTpmMeasureBootLib
|
||||||
|
CVE 2022-36764.
|
||||||
|
|
||||||
|
Cc: Jiewen Yao <jiewen.yao@intel.com>
|
||||||
|
|
||||||
|
Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
|
||||||
|
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
|
||||||
|
|
||||||
|
reference: https://github.com/tianocore/edk2/pull/5264
|
||||||
|
Signed-off-by: yexiao <yexiao7@huawei.com>
|
||||||
|
---
|
||||||
|
.../DxeTpmMeasureBootLib.c | 13 ++-
|
||||||
|
.../DxeTpmMeasureBootLibSanitization.c | 44 +++++++++
|
||||||
|
.../DxeTpmMeasureBootLibSanitization.h | 23 +++++
|
||||||
|
.../DxeTpmMeasureBootLibSanitizationTest.c | 98 +++++++++++++++++--
|
||||||
|
4 files changed, 168 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
|
||||||
|
index f31b49f8..23329185 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
|
||||||
|
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
+Copyright (c) Microsoft Corporation.<BR>
|
||||||
|
|
||||||
|
Copyright (c) Microsoft Corporation.<BR>
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
@@ -345,18 +346,22 @@ TcgMeasurePeImage (
|
||||||
|
ImageLoad = NULL;
|
||||||
|
SectionHeader = NULL;
|
||||||
|
Sha1Ctx = NULL;
|
||||||
|
+ TcgEvent = NULL;
|
||||||
|
FilePathSize = (UINT32)GetDevicePathSize (FilePath);
|
||||||
|
|
||||||
|
- //
|
||||||
|
// Determine destination PCR by BootPolicy
|
||||||
|
//
|
||||||
|
- EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize;
|
||||||
|
- TcgEvent = AllocateZeroPool (EventSize + sizeof (TCG_PCR_EVENT));
|
||||||
|
+ Status = SanitizePeImageEventSize (FilePathSize, &EventSize);
|
||||||
|
+ if (EFI_ERROR (Status)) {
|
||||||
|
+ return EFI_UNSUPPORTED;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ TcgEvent = AllocateZeroPool (EventSize);
|
||||||
|
if (TcgEvent == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- TcgEvent->EventSize = EventSize;
|
||||||
|
+ TcgEvent->EventSize = EventSize - sizeof (TCG_PCR_EVENT_HDR);
|
||||||
|
ImageLoad = (EFI_IMAGE_LOAD_EVENT *)TcgEvent->Event;
|
||||||
|
|
||||||
|
switch (ImageType) {
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c
|
||||||
|
index e009ce46..33a230f8 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c
|
||||||
|
@@ -239,3 +239,47 @@ SanitizePrimaryHeaderGptEventSize (
|
||||||
|
|
||||||
|
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 = 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 = SafeUint32Add (*EventSize, sizeof (TCG_PCR_EVENT_HDR), 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/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h
|
||||||
|
index 57e05e48..181aba42 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h
|
||||||
|
@@ -111,4 +111,27 @@ SanitizePrimaryHeaderGptEventSize (
|
||||||
|
OUT UINT32 *EventSize
|
||||||
|
);
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ 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/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c
|
||||||
|
index 8cd97480..77a67826 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c
|
||||||
|
@@ -1,8 +1,8 @@
|
||||||
|
/** @file
|
||||||
|
-This file includes the unit test cases for the DxeTpmMeasureBootLibSanitizationTest.c.
|
||||||
|
+ This file includes the unit test cases for the DxeTpmMeasureBootLibSanitizationTest.c.
|
||||||
|
|
||||||
|
-Copyright (c) Microsoft Corporation.<BR>
|
||||||
|
-SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
+ Copyright (c) Microsoft Corporation.<BR>
|
||||||
|
+ SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include <Uefi.h>
|
||||||
|
@@ -186,9 +186,6 @@ TestSanitizePrimaryHeaderGptEventSize (
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_PARTITION_TABLE_HEADER PrimaryHeader;
|
||||||
|
UINTN NumberOfPartition;
|
||||||
|
- EFI_GPT_DATA *GptData;
|
||||||
|
-
|
||||||
|
- GptData = NULL;
|
||||||
|
|
||||||
|
// Test that a normal PrimaryHeader passes validation
|
||||||
|
PrimaryHeader.NumberOfPartitionEntries = 5;
|
||||||
|
@@ -222,6 +219,94 @@ TestSanitizePrimaryHeaderGptEventSize (
|
||||||
|
return UNIT_TEST_PASSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ 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 calculating
|
||||||
|
+ 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 = UNIT_TEST_ERROR_TEST_FAILED;
|
||||||
|
+
|
||||||
|
+ // Generate EFI_DEVICE_PATH_PROTOCOL test data
|
||||||
|
+ DevicePath.Type = 0;
|
||||||
|
+ DevicePath.SubType = 0;
|
||||||
|
+ DevicePath.Length[0] = 0;
|
||||||
|
+ DevicePath.Length[1] = 0;
|
||||||
|
+
|
||||||
|
+ // Generate EFI_IMAGE_LOAD_EVENT test data
|
||||||
|
+ ImageLoadEvent = AllocateZeroPool (sizeof (EFI_IMAGE_LOAD_EVENT) + sizeof (EFI_DEVICE_PATH_PROTOCOL));
|
||||||
|
+ if (ImageLoadEvent == NULL) {
|
||||||
|
+ DEBUG ((DEBUG_ERROR, "%a: AllocateZeroPool failed\n", __func__));
|
||||||
|
+ goto Exit;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Populate EFI_IMAGE_LOAD_EVENT54 test data
|
||||||
|
+ ImageLoadEvent->ImageLocationInMemory = (EFI_PHYSICAL_ADDRESS)0x12345678;
|
||||||
|
+ ImageLoadEvent->ImageLengthInMemory = 0x1000;
|
||||||
|
+ ImageLoadEvent->ImageLinkTimeAddress = (UINTN)ImageLoadEvent;
|
||||||
|
+ ImageLoadEvent->LengthOfDevicePath = sizeof (EFI_DEVICE_PATH_PROTOCOL);
|
||||||
|
+ CopyMem (ImageLoadEvent->DevicePath, &DevicePath, sizeof (EFI_DEVICE_PATH_PROTOCOL));
|
||||||
|
+
|
||||||
|
+ FilePathSize = 255;
|
||||||
|
+
|
||||||
|
+ // Test that a normal PE image passes validation
|
||||||
|
+ Status = 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 = OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath) + FilePathSize;
|
||||||
|
+ ExistingLogicEventSize += sizeof (TCG_PCR_EVENT_HDR);
|
||||||
|
+
|
||||||
|
+ if (EventSize != ExistingLogicEventSize) {
|
||||||
|
+ UT_LOG_ERROR ("SanitizePeImageEventSize returned an incorrect event size. Expected %u, got %u\n", ExistingLogicEventSize, EventSize);
|
||||||
|
+ goto Exit;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Test that the event size may not overflow
|
||||||
|
+ Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize);
|
||||||
|
+ if (Status != EFI_BAD_BUFFER_SIZE) {
|
||||||
|
+ UT_LOG_ERROR ("SanitizePeImageEventSize succeded when it was supposed to fail with %r\n", Status);
|
||||||
|
+ goto Exit;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ TestStatus = UNIT_TEST_PASSED;
|
||||||
|
+Exit:
|
||||||
|
+
|
||||||
|
+ if (ImageLoadEvent != NULL) {
|
||||||
|
+ FreePool (ImageLoadEvent);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (TestStatus == 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", TestSanitizeEfiPartitionTableHeader, NULL, NULL, NULL);
|
||||||
|
AddTestCase (TcgMeasureBootLibValidationTestSuite, "Tests Primary header gpt event checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePrimaryHeaderAllocationSize, 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 FileSize checks for overflow", "Common.TcgMeasureBootLibValidation", TestSanitizePeImageEventSize, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
Status = RunAllTestSuites (Framework);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
From 02c99cab3ac4b61a9e274e1db7802a06e772abaf Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Douglas Flick [MSFT]" <doug.edk2@gmail.com>
|
||||||
|
Date: Fri, 12 Jan 2024 02:16:06 +0800
|
||||||
|
Subject: [PATCH 06/10] SecurityPkg: : Adding CVE 2022-36764 to
|
||||||
|
SecurityFixes.yaml
|
||||||
|
|
||||||
|
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 <jiewen.yao@intel.com>
|
||||||
|
|
||||||
|
Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
|
||||||
|
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
|
||||||
|
|
||||||
|
reference: https://github.com/tianocore/edk2/pull/5264
|
||||||
|
Signed-off-by: yexiao <yexiao7@huawei.com>
|
||||||
|
---
|
||||||
|
SecurityPkg/SecurityFixes.yaml | 14 ++++++++++++++
|
||||||
|
1 file changed, 14 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/SecurityPkg/SecurityFixes.yaml b/SecurityPkg/SecurityFixes.yaml
|
||||||
|
index 36ac267e..ceaaa256 100644
|
||||||
|
--- a/SecurityPkg/SecurityFixes.yaml
|
||||||
|
+++ b/SecurityPkg/SecurityFixes.yaml
|
||||||
|
@@ -20,3 +20,17 @@ CVE_2022_36763:
|
||||||
|
- https://bugzilla.tianocore.org/show_bug.cgi?id=4117
|
||||||
|
- https://bugzilla.tianocore.org/show_bug.cgi?id=2168
|
||||||
|
- https://bugzilla.tianocore.org/show_bug.cgi?id=1990
|
||||||
|
+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=4118
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
257
0018-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch
Normal file
257
0018-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
From bfdc271e28418b8a1b50d09112c48c371087efd1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Doug Flick <dougflick@microsoft.com>
|
||||||
|
Date: Wed, 17 Jan 2024 14:47:20 -0800
|
||||||
|
Subject: [PATCH 07/10] SecurityPkg: DxeTpm2MeasureBootLib: SECURITY PATCH
|
||||||
|
4117/4118 symbol rename
|
||||||
|
|
||||||
|
Updates the sanitation function names to be lib unique names
|
||||||
|
|
||||||
|
Cc: Jiewen Yao <jiewen.yao@intel.com>
|
||||||
|
Cc: Rahul Kumar <rahul1.kumar@intel.com>
|
||||||
|
|
||||||
|
Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
|
||||||
|
Message-Id: <7b18434c8a8b561654efd40ced3becb8b378c8f1.1705529990.git.doug.edk2@gmail.com>
|
||||||
|
Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
|
||||||
|
|
||||||
|
reference: https://github.com/tianocore/edk2/pull/5273
|
||||||
|
Signed-off-by: yexiao <yexiao7@huawei.com>
|
||||||
|
---
|
||||||
|
.../DxeTpm2MeasureBootLib.c | 8 +++---
|
||||||
|
.../DxeTpm2MeasureBootLibSanitization.c | 8 +++---
|
||||||
|
.../DxeTpm2MeasureBootLibSanitization.h | 8 +++---
|
||||||
|
.../DxeTpm2MeasureBootLibSanitizationTest.c | 26 +++++++++----------
|
||||||
|
4 files changed, 25 insertions(+), 25 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c
|
||||||
|
index ffab7968..cc58b8bf 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c
|
||||||
|
@@ -200,7 +200,7 @@ Tcg2MeasureGptTable (
|
||||||
|
BlockIo->Media->BlockSize,
|
||||||
|
(UINT8 *)PrimaryHeader
|
||||||
|
);
|
||||||
|
- if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) {
|
||||||
|
+ if (EFI_ERROR (Status) || EFI_ERROR (Tpm2SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n"));
|
||||||
|
FreePool (PrimaryHeader);
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
@@ -209,7 +209,7 @@ Tcg2MeasureGptTable (
|
||||||
|
//
|
||||||
|
// Read the partition entry.
|
||||||
|
//
|
||||||
|
- Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize);
|
||||||
|
+ Status = Tpm2SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
FreePool (PrimaryHeader);
|
||||||
|
return EFI_BAD_BUFFER_SIZE;
|
||||||
|
@@ -250,7 +250,7 @@ Tcg2MeasureGptTable (
|
||||||
|
//
|
||||||
|
// Prepare Data for Measurement (CcProtocol and Tcg2Protocol)
|
||||||
|
//
|
||||||
|
- Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &TcgEventSize);
|
||||||
|
+ Status = Tpm2SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &TcgEventSize);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
FreePool (PrimaryHeader);
|
||||||
|
FreePool (EntryPtr);
|
||||||
|
@@ -420,7 +420,7 @@ Tcg2MeasurePeImage (
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePathSize = (UINT32)GetDevicePathSize (FilePath);
|
||||||
|
- Status = SanitizePeImageEventSize (FilePathSize, &EventSize);
|
||||||
|
+ Status = Tpm2SanitizePeImageEventSize (FilePathSize, &EventSize);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c
|
||||||
|
index bc583c97..d911efe6 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.c
|
||||||
|
@@ -63,7 +63,7 @@
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
-SanitizeEfiPartitionTableHeader (
|
||||||
|
+Tpm2SanitizeEfiPartitionTableHeader (
|
||||||
|
IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
|
||||||
|
IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo
|
||||||
|
)
|
||||||
|
@@ -169,7 +169,7 @@ SanitizeEfiPartitionTableHeader (
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
-SanitizePrimaryHeaderAllocationSize (
|
||||||
|
+Tpm2SanitizePrimaryHeaderAllocationSize (
|
||||||
|
IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
|
||||||
|
OUT UINT32 *AllocationSize
|
||||||
|
)
|
||||||
|
@@ -221,7 +221,7 @@ SanitizePrimaryHeaderAllocationSize (
|
||||||
|
One of the passed parameters was invalid.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
-SanitizePrimaryHeaderGptEventSize (
|
||||||
|
+Tpm2SanitizePrimaryHeaderGptEventSize (
|
||||||
|
IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
|
||||||
|
IN UINTN NumberOfPartition,
|
||||||
|
OUT UINT32 *EventSize
|
||||||
|
@@ -292,7 +292,7 @@ SanitizePrimaryHeaderGptEventSize (
|
||||||
|
One of the passed parameters was invalid.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
-SanitizePeImageEventSize (
|
||||||
|
+Tpm2SanitizePeImageEventSize (
|
||||||
|
IN UINT32 FilePathSize,
|
||||||
|
OUT UINT32 *EventSize
|
||||||
|
)
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h
|
||||||
|
index bfbfb589..504958f4 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLibSanitization.h
|
||||||
|
@@ -54,7 +54,7 @@
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
-SanitizeEfiPartitionTableHeader (
|
||||||
|
+Tpm2SanitizeEfiPartitionTableHeader (
|
||||||
|
IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
|
||||||
|
IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo
|
||||||
|
);
|
||||||
|
@@ -78,7 +78,7 @@ SanitizeEfiPartitionTableHeader (
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
-SanitizePrimaryHeaderAllocationSize (
|
||||||
|
+Tpm2SanitizePrimaryHeaderAllocationSize (
|
||||||
|
IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
|
||||||
|
OUT UINT32 *AllocationSize
|
||||||
|
);
|
||||||
|
@@ -107,7 +107,7 @@ SanitizePrimaryHeaderAllocationSize (
|
||||||
|
One of the passed parameters was invalid.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
-SanitizePrimaryHeaderGptEventSize (
|
||||||
|
+Tpm2SanitizePrimaryHeaderGptEventSize (
|
||||||
|
IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
|
||||||
|
IN UINTN NumberOfPartition,
|
||||||
|
OUT UINT32 *EventSize
|
||||||
|
@@ -131,7 +131,7 @@ SanitizePrimaryHeaderGptEventSize (
|
||||||
|
One of the passed parameters was invalid.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
-SanitizePeImageEventSize (
|
||||||
|
+Tpm2SanitizePeImageEventSize (
|
||||||
|
IN UINT32 FilePathSize,
|
||||||
|
OUT UINT32 *EventSize
|
||||||
|
);
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c
|
||||||
|
index 8d8c0b26..0e33fec5 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/InternalUnitTest/DxeTpm2MeasureBootLibSanitizationTest.c
|
||||||
|
@@ -84,27 +84,27 @@ TestSanitizeEfiPartitionTableHeader (
|
||||||
|
PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize);
|
||||||
|
|
||||||
|
// Test that a normal PrimaryHeader passes validation
|
||||||
|
- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
+ Status = Tpm2SanitizeEfiPartitionTableHeader (&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 = 0;
|
||||||
|
- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
+ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR);
|
||||||
|
PrimaryHeader.NumberOfPartitionEntries = 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 = 0;
|
||||||
|
- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
+ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR);
|
||||||
|
PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER);
|
||||||
|
|
||||||
|
// Test that when the SizeOfPartitionEntry is too small, the function returns 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, 512, etc.)!"
|
||||||
|
PrimaryHeader.SizeOfPartitionEntry = 1;
|
||||||
|
- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
+ Status = Tpm2SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR);
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__));
|
||||||
|
@@ -137,7 +137,7 @@ TestSanitizePrimaryHeaderAllocationSize (
|
||||||
|
PrimaryHeader.NumberOfPartitionEntries = 5;
|
||||||
|
PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY;
|
||||||
|
|
||||||
|
- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
+ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
UT_ASSERT_NOT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
// Test that the allocation size is correct compared to the existing logic
|
||||||
|
@@ -146,19 +146,19 @@ TestSanitizePrimaryHeaderAllocationSize (
|
||||||
|
// Test that an overflow is detected
|
||||||
|
PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32;
|
||||||
|
PrimaryHeader.SizeOfPartitionEntry = 5;
|
||||||
|
- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
+ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
|
||||||
|
// Test the inverse
|
||||||
|
PrimaryHeader.NumberOfPartitionEntries = 5;
|
||||||
|
PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32;
|
||||||
|
- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
+ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
|
||||||
|
// Test the worst case scenario
|
||||||
|
PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32;
|
||||||
|
PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32;
|
||||||
|
- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
+ Status = Tpm2SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__));
|
||||||
|
@@ -196,7 +196,7 @@ TestSanitizePrimaryHeaderGptEventSize (
|
||||||
|
NumberOfPartition = 13;
|
||||||
|
|
||||||
|
// that the primary event size is correct
|
||||||
|
- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize);
|
||||||
|
+ Status = Tpm2SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize);
|
||||||
|
UT_ASSERT_NOT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
// Calculate the existing logic event size
|
||||||
|
@@ -207,12 +207,12 @@ TestSanitizePrimaryHeaderGptEventSize (
|
||||||
|
UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize);
|
||||||
|
|
||||||
|
// Tests that the primary event size may not overflow
|
||||||
|
- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize);
|
||||||
|
+ Status = Tpm2SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
|
||||||
|
// Test that the size of partition entries may not overflow
|
||||||
|
PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32;
|
||||||
|
- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize);
|
||||||
|
+ Status = Tpm2SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__));
|
||||||
|
@@ -245,7 +245,7 @@ TestSanitizePeImageEventSize (
|
||||||
|
FilePathSize = 255;
|
||||||
|
|
||||||
|
// Test that a normal PE image passes validation
|
||||||
|
- Status = SanitizePeImageEventSize (FilePathSize, &EventSize);
|
||||||
|
+ Status = Tpm2SanitizePeImageEventSize (FilePathSize, &EventSize);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_SUCCESS);
|
||||||
|
|
||||||
|
// Test that the event size is correct compared to the existing logic
|
||||||
|
@@ -258,7 +258,7 @@ TestSanitizePeImageEventSize (
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that the event size may not overflow
|
||||||
|
- Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize);
|
||||||
|
+ Status = Tpm2SanitizePeImageEventSize (MAX_UINT32, &EventSize);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__));
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
264
0019-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch
Normal file
264
0019-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
From 9c71ea26dff1adc7433fd15a27e46d53bc932711 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Doug Flick <dougflick@microsoft.com>
|
||||||
|
Date: Wed, 17 Jan 2024 14:47:21 -0800
|
||||||
|
Subject: [PATCH 08/10] SecurityPkg: DxeTpmMeasureBootLib: SECURITY PATCH
|
||||||
|
4117/4118 symbol rename
|
||||||
|
|
||||||
|
Updates the sanitation function names to be lib unique names
|
||||||
|
|
||||||
|
Cc: Jiewen Yao <jiewen.yao@intel.com>
|
||||||
|
Cc: Rahul Kumar <rahul1.kumar@intel.com>
|
||||||
|
|
||||||
|
Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com>
|
||||||
|
Message-Id: <355aa846a99ca6ac0f7574cf5982661da0d9fea6.1705529990.git.doug.edk2@gmail.com>
|
||||||
|
Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
|
||||||
|
|
||||||
|
reference: https://github.com/tianocore/edk2/pull/5273
|
||||||
|
Signed-off-by: yexiao <yexiao7@huawei.com>
|
||||||
|
---
|
||||||
|
.../DxeTpmMeasureBootLib.c | 8 +++---
|
||||||
|
.../DxeTpmMeasureBootLibSanitization.c | 10 +++----
|
||||||
|
.../DxeTpmMeasureBootLibSanitization.h | 8 +++---
|
||||||
|
.../DxeTpmMeasureBootLibSanitizationTest.c | 26 +++++++++----------
|
||||||
|
4 files changed, 26 insertions(+), 26 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
|
||||||
|
index 23329185..cf358e35 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
|
||||||
|
@@ -174,7 +174,7 @@ TcgMeasureGptTable (
|
||||||
|
BlockIo->Media->BlockSize,
|
||||||
|
(UINT8 *)PrimaryHeader
|
||||||
|
);
|
||||||
|
- if (EFI_ERROR (Status) || EFI_ERROR (SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) {
|
||||||
|
+ if (EFI_ERROR (Status) || EFI_ERROR (TpmSanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n"));
|
||||||
|
FreePool (PrimaryHeader);
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
@@ -183,7 +183,7 @@ TcgMeasureGptTable (
|
||||||
|
//
|
||||||
|
// Read the partition entry.
|
||||||
|
//
|
||||||
|
- Status = SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize);
|
||||||
|
+ Status = TpmSanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
FreePool (PrimaryHeader);
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
@@ -224,7 +224,7 @@ TcgMeasureGptTable (
|
||||||
|
//
|
||||||
|
// Prepare Data for Measurement
|
||||||
|
//
|
||||||
|
- Status = SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &EventSize);
|
||||||
|
+ Status = TpmSanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &EventSize);
|
||||||
|
TcgEvent = (TCG_PCR_EVENT *)AllocateZeroPool (EventSize);
|
||||||
|
if (TcgEvent == NULL) {
|
||||||
|
FreePool (PrimaryHeader);
|
||||||
|
@@ -351,7 +351,7 @@ TcgMeasurePeImage (
|
||||||
|
|
||||||
|
// Determine destination PCR by BootPolicy
|
||||||
|
//
|
||||||
|
- Status = SanitizePeImageEventSize (FilePathSize, &EventSize);
|
||||||
|
+ Status = TpmSanitizePeImageEventSize (FilePathSize, &EventSize);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c
|
||||||
|
index 33a230f8..c72a3491 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.c
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
/** @file
|
||||||
|
- The library instance provides security service of TPM2 measure boot and
|
||||||
|
+ The library instance provides security service of TPM measure boot and
|
||||||
|
Confidential Computing (CC) measure boot.
|
||||||
|
|
||||||
|
Caution: This file requires additional review when modified.
|
||||||
|
@@ -63,7 +63,7 @@
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
-SanitizeEfiPartitionTableHeader (
|
||||||
|
+TpmSanitizeEfiPartitionTableHeader (
|
||||||
|
IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
|
||||||
|
IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo
|
||||||
|
)
|
||||||
|
@@ -145,7 +145,7 @@ SanitizeEfiPartitionTableHeader (
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
-SanitizePrimaryHeaderAllocationSize (
|
||||||
|
+TpmSanitizePrimaryHeaderAllocationSize (
|
||||||
|
IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
|
||||||
|
OUT UINT32 *AllocationSize
|
||||||
|
)
|
||||||
|
@@ -194,7 +194,7 @@ SanitizePrimaryHeaderAllocationSize (
|
||||||
|
One of the passed parameters was invalid.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
-SanitizePrimaryHeaderGptEventSize (
|
||||||
|
+TpmSanitizePrimaryHeaderGptEventSize (
|
||||||
|
IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
|
||||||
|
IN UINTN NumberOfPartition,
|
||||||
|
OUT UINT32 *EventSize
|
||||||
|
@@ -258,7 +258,7 @@ SanitizePrimaryHeaderGptEventSize (
|
||||||
|
One of the passed parameters was invalid.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
-SanitizePeImageEventSize (
|
||||||
|
+TpmSanitizePeImageEventSize (
|
||||||
|
IN UINT32 FilePathSize,
|
||||||
|
OUT UINT32 *EventSize
|
||||||
|
)
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h
|
||||||
|
index 181aba42..bbde1010 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLibSanitization.h
|
||||||
|
@@ -53,7 +53,7 @@
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
-SanitizeEfiPartitionTableHeader (
|
||||||
|
+TpmSanitizeEfiPartitionTableHeader (
|
||||||
|
IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
|
||||||
|
IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo
|
||||||
|
);
|
||||||
|
@@ -77,7 +77,7 @@ SanitizeEfiPartitionTableHeader (
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
-SanitizePrimaryHeaderAllocationSize (
|
||||||
|
+TpmSanitizePrimaryHeaderAllocationSize (
|
||||||
|
IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
|
||||||
|
OUT UINT32 *AllocationSize
|
||||||
|
);
|
||||||
|
@@ -105,7 +105,7 @@ SanitizePrimaryHeaderAllocationSize (
|
||||||
|
One of the passed parameters was invalid.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
-SanitizePrimaryHeaderGptEventSize (
|
||||||
|
+TpmSanitizePrimaryHeaderGptEventSize (
|
||||||
|
IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
|
||||||
|
IN UINTN NumberOfPartition,
|
||||||
|
OUT UINT32 *EventSize
|
||||||
|
@@ -129,7 +129,7 @@ SanitizePrimaryHeaderGptEventSize (
|
||||||
|
One of the passed parameters was invalid.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
-SanitizePeImageEventSize (
|
||||||
|
+TpmSanitizePeImageEventSize (
|
||||||
|
IN UINT32 FilePathSize,
|
||||||
|
OUT UINT32 *EventSize
|
||||||
|
);
|
||||||
|
diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c
|
||||||
|
index 77a67826..e00dfaba 100644
|
||||||
|
--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c
|
||||||
|
+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/InternalUnitTest/DxeTpmMeasureBootLibSanitizationTest.c
|
||||||
|
@@ -83,27 +83,27 @@ TestSanitizeEfiPartitionTableHeader (
|
||||||
|
PrimaryHeader.Header.CRC32 = CalculateCrc32 ((UINT8 *)&PrimaryHeader, PrimaryHeader.Header.HeaderSize);
|
||||||
|
|
||||||
|
// Test that a normal PrimaryHeader passes validation
|
||||||
|
- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
+ Status = TpmSanitizeEfiPartitionTableHeader (&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 = 0;
|
||||||
|
- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
+ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR);
|
||||||
|
PrimaryHeader.NumberOfPartitionEntries = 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 = 0;
|
||||||
|
- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
+ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR);
|
||||||
|
PrimaryHeader.Header.HeaderSize = sizeof (EFI_PARTITION_TABLE_HEADER);
|
||||||
|
|
||||||
|
// Test that when the SizeOfPartitionEntry is too small, the function returns 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, 512, etc.)!"
|
||||||
|
PrimaryHeader.SizeOfPartitionEntry = 1;
|
||||||
|
- Status = SanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
+ Status = TpmSanitizeEfiPartitionTableHeader (&PrimaryHeader, &BlockIo);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_DEVICE_ERROR);
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__));
|
||||||
|
@@ -136,7 +136,7 @@ TestSanitizePrimaryHeaderAllocationSize (
|
||||||
|
PrimaryHeader.NumberOfPartitionEntries = 5;
|
||||||
|
PrimaryHeader.SizeOfPartitionEntry = DEFAULT_PRIMARY_TABLE_HEADER_SIZE_OF_PARTITION_ENTRY;
|
||||||
|
|
||||||
|
- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
+ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
UT_ASSERT_NOT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
// Test that the allocation size is correct compared to the existing logic
|
||||||
|
@@ -145,19 +145,19 @@ TestSanitizePrimaryHeaderAllocationSize (
|
||||||
|
// Test that an overflow is detected
|
||||||
|
PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32;
|
||||||
|
PrimaryHeader.SizeOfPartitionEntry = 5;
|
||||||
|
- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
+ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
|
||||||
|
// Test the inverse
|
||||||
|
PrimaryHeader.NumberOfPartitionEntries = 5;
|
||||||
|
PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32;
|
||||||
|
- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
+ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
|
||||||
|
// Test the worst case scenario
|
||||||
|
PrimaryHeader.NumberOfPartitionEntries = MAX_UINT32;
|
||||||
|
PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32;
|
||||||
|
- Status = SanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
+ Status = TpmSanitizePrimaryHeaderAllocationSize (&PrimaryHeader, &AllocationSize);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__));
|
||||||
|
@@ -195,7 +195,7 @@ TestSanitizePrimaryHeaderGptEventSize (
|
||||||
|
NumberOfPartition = 13;
|
||||||
|
|
||||||
|
// that the primary event size is correct
|
||||||
|
- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize);
|
||||||
|
+ Status = TpmSanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize);
|
||||||
|
UT_ASSERT_NOT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
// Calculate the existing logic event size
|
||||||
|
@@ -206,12 +206,12 @@ TestSanitizePrimaryHeaderGptEventSize (
|
||||||
|
UT_ASSERT_EQUAL (EventSize, ExistingLogicEventSize);
|
||||||
|
|
||||||
|
// Tests that the primary event size may not overflow
|
||||||
|
- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize);
|
||||||
|
+ Status = TpmSanitizePrimaryHeaderGptEventSize (&PrimaryHeader, MAX_UINT32, &EventSize);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
|
||||||
|
// Test that the size of partition entries may not overflow
|
||||||
|
PrimaryHeader.SizeOfPartitionEntry = MAX_UINT32;
|
||||||
|
- Status = SanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize);
|
||||||
|
+ Status = TpmSanitizePrimaryHeaderGptEventSize (&PrimaryHeader, NumberOfPartition, &EventSize);
|
||||||
|
UT_ASSERT_EQUAL (Status, EFI_BAD_BUFFER_SIZE);
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_INFO, "%a: Test passed\n", __func__));
|
||||||
|
@@ -269,7 +269,7 @@ TestSanitizePeImageEventSize (
|
||||||
|
FilePathSize = 255;
|
||||||
|
|
||||||
|
// Test that a normal PE image passes validation
|
||||||
|
- Status = SanitizePeImageEventSize (FilePathSize, &EventSize);
|
||||||
|
+ Status = TpmSanitizePeImageEventSize (FilePathSize, &EventSize);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
UT_LOG_ERROR ("SanitizePeImageEventSize failed with %r\n", Status);
|
||||||
|
goto Exit;
|
||||||
|
@@ -285,7 +285,7 @@ TestSanitizePeImageEventSize (
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that the event size may not overflow
|
||||||
|
- Status = SanitizePeImageEventSize (MAX_UINT32, &EventSize);
|
||||||
|
+ Status = TpmSanitizePeImageEventSize (MAX_UINT32, &EventSize);
|
||||||
|
if (Status != EFI_BAD_BUFFER_SIZE) {
|
||||||
|
UT_LOG_ERROR ("SanitizePeImageEventSize succeded when it was supposed to fail with %r\n", Status);
|
||||||
|
goto Exit;
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
154
0020-EmbeddedPkg-Hob-Integer-Overflow-in-CreateHob.patch
Normal file
154
0020-EmbeddedPkg-Hob-Integer-Overflow-in-CreateHob.patch
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
From 73ef289cdda1352b5fabf4ba281993e2ba91b511 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gua Guo <gua.guo@intel.com>
|
||||||
|
Date: Thu, 11 Jan 2024 13:07:50 +0800
|
||||||
|
Subject: [PATCH 09/10] EmbeddedPkg/Hob: Integer Overflow in CreateHob()
|
||||||
|
|
||||||
|
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4166
|
||||||
|
|
||||||
|
Fix integer overflow in various CreateHob instances.
|
||||||
|
Fixes: CVE-2022-36765
|
||||||
|
|
||||||
|
The CreateHob() function aligns the requested size to 8
|
||||||
|
performing the following operation:
|
||||||
|
```
|
||||||
|
HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
|
||||||
|
```
|
||||||
|
|
||||||
|
No checks are performed to ensure this value doesn't
|
||||||
|
overflow, and could lead to CreateHob() returning a smaller
|
||||||
|
HOB than requested, which could lead to OOB HOB accesses.
|
||||||
|
|
||||||
|
Reported-by: Marc Beatove <mbeatove@google.com>
|
||||||
|
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
|
||||||
|
Reviewed-by: Ard Biesheuvel <ardb+tianocore@kernel.org>
|
||||||
|
Cc: Abner Chang <abner.chang@amd.com>
|
||||||
|
Cc: John Mathew <john.mathews@intel.com>
|
||||||
|
Authored-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Signed-off-by: Gua Guo <gua.guo@intel.com>
|
||||||
|
|
||||||
|
reference: https://github.com/tianocore/edk2/pull/5273
|
||||||
|
Signed-off-by: yexiao <yexiao7@huawei.com>
|
||||||
|
---
|
||||||
|
EmbeddedPkg/Library/PrePiHobLib/Hob.c | 43 +++++++++++++++++++++++++++
|
||||||
|
1 file changed, 43 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/EmbeddedPkg/Library/PrePiHobLib/Hob.c b/EmbeddedPkg/Library/PrePiHobLib/Hob.c
|
||||||
|
index 8eb175aa..d771497f 100644
|
||||||
|
--- a/EmbeddedPkg/Library/PrePiHobLib/Hob.c
|
||||||
|
+++ b/EmbeddedPkg/Library/PrePiHobLib/Hob.c
|
||||||
|
@@ -110,6 +110,13 @@ CreateHob (
|
||||||
|
|
||||||
|
HandOffHob = GetHobList ();
|
||||||
|
|
||||||
|
+ //
|
||||||
|
+ // Check Length to avoid data overflow.
|
||||||
|
+ //
|
||||||
|
+ if (HobLength > MAX_UINT16 - 0x7) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
|
||||||
|
|
||||||
|
FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
|
||||||
|
@@ -160,6 +167,9 @@ BuildResourceDescriptorHob (
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
|
||||||
|
ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
Hob->ResourceType = ResourceType;
|
||||||
|
Hob->ResourceAttribute = ResourceAttribute;
|
||||||
|
@@ -401,6 +411,10 @@ BuildModuleHob (
|
||||||
|
);
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
|
||||||
|
+ ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
|
||||||
|
Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
|
||||||
|
@@ -449,6 +463,11 @@ BuildGuidHob (
|
||||||
|
ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16)(sizeof (EFI_HOB_GUID_TYPE) + DataLength));
|
||||||
|
+ ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
CopyGuid (&Hob->Name, Guid);
|
||||||
|
return Hob + 1;
|
||||||
|
}
|
||||||
|
@@ -512,6 +531,10 @@ BuildFvHob (
|
||||||
|
EFI_HOB_FIRMWARE_VOLUME *Hob;
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
|
||||||
|
+ ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
Hob->BaseAddress = BaseAddress;
|
||||||
|
Hob->Length = Length;
|
||||||
|
@@ -543,6 +566,10 @@ BuildFv2Hob (
|
||||||
|
EFI_HOB_FIRMWARE_VOLUME2 *Hob;
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
|
||||||
|
+ ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
Hob->BaseAddress = BaseAddress;
|
||||||
|
Hob->Length = Length;
|
||||||
|
@@ -584,6 +611,10 @@ BuildFv3Hob (
|
||||||
|
EFI_HOB_FIRMWARE_VOLUME3 *Hob;
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_FV3, sizeof (EFI_HOB_FIRMWARE_VOLUME3));
|
||||||
|
+ ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
Hob->BaseAddress = BaseAddress;
|
||||||
|
Hob->Length = Length;
|
||||||
|
@@ -639,6 +670,10 @@ BuildCpuHob (
|
||||||
|
EFI_HOB_CPU *Hob;
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
|
||||||
|
+ ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
Hob->SizeOfMemorySpace = SizeOfMemorySpace;
|
||||||
|
Hob->SizeOfIoSpace = SizeOfIoSpace;
|
||||||
|
@@ -676,6 +711,10 @@ BuildStackHob (
|
||||||
|
);
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));
|
||||||
|
+ ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);
|
||||||
|
Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
|
||||||
|
@@ -756,6 +795,10 @@ BuildMemoryAllocationHob (
|
||||||
|
);
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
|
||||||
|
+ ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
|
||||||
|
Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
132
0021-StandaloneMmPkg-Hob-Integer-Overflow-in-CreateHob.patch
Normal file
132
0021-StandaloneMmPkg-Hob-Integer-Overflow-in-CreateHob.patch
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
From d1b5a360b8b4d8833c0f0e8de309a756b0cec347 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gua Guo <gua.guo@intel.com>
|
||||||
|
Date: Thu, 11 Jan 2024 13:03:26 +0800
|
||||||
|
Subject: [PATCH 10/10] StandaloneMmPkg/Hob: Integer Overflow in CreateHob()
|
||||||
|
|
||||||
|
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4166
|
||||||
|
|
||||||
|
Fix integer overflow in various CreateHob instances.
|
||||||
|
Fixes: CVE-2022-36765
|
||||||
|
|
||||||
|
The CreateHob() function aligns the requested size to 8
|
||||||
|
performing the following operation:
|
||||||
|
```
|
||||||
|
HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
|
||||||
|
```
|
||||||
|
|
||||||
|
No checks are performed to ensure this value doesn't
|
||||||
|
overflow, and could lead to CreateHob() returning a smaller
|
||||||
|
HOB than requested, which could lead to OOB HOB accesses.
|
||||||
|
|
||||||
|
Reported-by: Marc Beatove <mbeatove@google.com>
|
||||||
|
Reviewed-by: Ard Biesheuvel <ardb+tianocore@kernel.org>
|
||||||
|
Cc: Sami Mujawar <sami.mujawar@arm.com>
|
||||||
|
Reviewed-by: Ray Ni <ray.ni@intel.com>
|
||||||
|
Cc: John Mathew <john.mathews@intel.com>
|
||||||
|
Authored-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Signed-off-by: Gua Guo <gua.guo@intel.com>
|
||||||
|
|
||||||
|
reference: https://github.com/tianocore/edk2/pull/5273
|
||||||
|
Signed-off-by: yexiao <yexiao7@huawei.com>
|
||||||
|
---
|
||||||
|
.../Arm/StandaloneMmCoreHobLib.c | 35 +++++++++++++++++++
|
||||||
|
1 file changed, 35 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/Arm/StandaloneMmCoreHobLib.c b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/Arm/StandaloneMmCoreHobLib.c
|
||||||
|
index 1550e1ba..78677936 100644
|
||||||
|
--- a/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/Arm/StandaloneMmCoreHobLib.c
|
||||||
|
+++ b/StandaloneMmPkg/Library/StandaloneMmCoreHobLib/Arm/StandaloneMmCoreHobLib.c
|
||||||
|
@@ -34,6 +34,13 @@ CreateHob (
|
||||||
|
|
||||||
|
HandOffHob = GetHobList ();
|
||||||
|
|
||||||
|
+ //
|
||||||
|
+ // Check Length to avoid data overflow.
|
||||||
|
+ //
|
||||||
|
+ if (HobLength > MAX_UINT16 - 0x7) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
|
||||||
|
|
||||||
|
FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
|
||||||
|
@@ -89,6 +96,10 @@ BuildModuleHob (
|
||||||
|
);
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
|
||||||
|
+ ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
|
||||||
|
Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
|
||||||
|
@@ -129,6 +140,9 @@ BuildResourceDescriptorHob (
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
|
||||||
|
ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
Hob->ResourceType = ResourceType;
|
||||||
|
Hob->ResourceAttribute = ResourceAttribute;
|
||||||
|
@@ -167,6 +181,11 @@ BuildGuidHob (
|
||||||
|
ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16)(sizeof (EFI_HOB_GUID_TYPE) + DataLength));
|
||||||
|
+ ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
CopyGuid (&Hob->Name, Guid);
|
||||||
|
return Hob + 1;
|
||||||
|
}
|
||||||
|
@@ -226,6 +245,10 @@ BuildFvHob (
|
||||||
|
EFI_HOB_FIRMWARE_VOLUME *Hob;
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
|
||||||
|
+ ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
Hob->BaseAddress = BaseAddress;
|
||||||
|
Hob->Length = Length;
|
||||||
|
@@ -255,6 +278,10 @@ BuildFv2Hob (
|
||||||
|
EFI_HOB_FIRMWARE_VOLUME2 *Hob;
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
|
||||||
|
+ ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
Hob->BaseAddress = BaseAddress;
|
||||||
|
Hob->Length = Length;
|
||||||
|
@@ -282,6 +309,10 @@ BuildCpuHob (
|
||||||
|
EFI_HOB_CPU *Hob;
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
|
||||||
|
+ ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
Hob->SizeOfMemorySpace = SizeOfMemorySpace;
|
||||||
|
Hob->SizeOfIoSpace = SizeOfIoSpace;
|
||||||
|
@@ -319,6 +350,10 @@ BuildMemoryAllocationHob (
|
||||||
|
);
|
||||||
|
|
||||||
|
Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
|
||||||
|
+ ASSERT (Hob != NULL);
|
||||||
|
+ if (Hob == NULL) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
|
||||||
|
Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
15
edk2.spec
15
edk2.spec
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
Name: edk2
|
Name: edk2
|
||||||
Version: %{stable_date}
|
Version: %{stable_date}
|
||||||
Release: 3
|
Release: 4
|
||||||
Summary: EFI Development Kit II
|
Summary: EFI Development Kit II
|
||||||
License: BSD-2-Clause-Patent and OpenSSL and MIT
|
License: BSD-2-Clause-Patent and OpenSSL and MIT
|
||||||
URL: https://github.com/tianocore/edk2
|
URL: https://github.com/tianocore/edk2
|
||||||
@ -29,6 +29,16 @@ patch7: 0008-DH_check-Do-not-try-checking-q-properties-if-it-is-o.patch
|
|||||||
patch8: 0009-dhtest.c-Add-test-of-DH_check-with-q-p-1.patch
|
patch8: 0009-dhtest.c-Add-test-of-DH_check-with-q-p-1.patch
|
||||||
patch9: 0010-Add-NULL-checks-where-ContentInfo-data-can-be-NULL.patch
|
patch9: 0010-Add-NULL-checks-where-ContentInfo-data-can-be-NULL.patch
|
||||||
patch10: 0011-poly1305-ppc.pl-Fix-vector-register-clobbering.patch
|
patch10: 0011-poly1305-ppc.pl-Fix-vector-register-clobbering.patch
|
||||||
|
patch11: 0012-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch
|
||||||
|
patch12: 0013-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch
|
||||||
|
patch13: 0014-SecurityPkg-Adding-CVE-2022-36763-to-SecurityFixes.y.patch
|
||||||
|
patch14: 0015-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch
|
||||||
|
patch15: 0016-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4118.patch
|
||||||
|
patch16: 0017-SecurityPkg-Adding-CVE-2022-36764-to-SecurityFixes.y.patch
|
||||||
|
patch17: 0018-SecurityPkg-DxeTpm2MeasureBootLib-SECURITY-PATCH-411.patch
|
||||||
|
patch18: 0019-SecurityPkg-DxeTpmMeasureBootLib-SECURITY-PATCH-4117.patch
|
||||||
|
patch19: 0020-EmbeddedPkg-Hob-Integer-Overflow-in-CreateHob.patch
|
||||||
|
patch20: 0021-StandaloneMmPkg-Hob-Integer-Overflow-in-CreateHob.patch
|
||||||
|
|
||||||
BuildRequires: acpica-tools gcc gcc-c++ libuuid-devel python3 bc nasm python3-unversioned-command isl
|
BuildRequires: acpica-tools gcc gcc-c++ libuuid-devel python3 bc nasm python3-unversioned-command isl
|
||||||
|
|
||||||
@ -266,6 +276,9 @@ chmod +x %{buildroot}%{_bindir}/Rsa2048Sha256GenerateKeys
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Mar 5 2024 yexiao<yexiao7@huawei.com> - 202308-4
|
||||||
|
- fix CVE-2022-36763、CVE-2022-36764、CVE-2022-36765
|
||||||
|
|
||||||
* Sat Feb 24 2024 yexiao <yexiao7@huawei.com> - 202308-3
|
* Sat Feb 24 2024 yexiao <yexiao7@huawei.com> - 202308-3
|
||||||
- Fix CVE-2023-3446、CVE-2023-3817、CVE-2024-0727、CVE-2023-2975、CVE-2023-6129
|
- Fix CVE-2023-3446、CVE-2023-3817、CVE-2024-0727、CVE-2023-2975、CVE-2023-6129
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user