mirror of https://github.com/acidanthera/audk.git
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>
This commit is contained in:
parent
c7b2794421
commit
0d341c01ee
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue