mirror of
https://github.com/tianocore/edk2
synced 2026-08-27 00:23:19 -04:00
MdeModulePkg/GptLib: Add host-based unit tests for malformed GPT input
Extend the GptLib host-based tests with negative cases that guard the security hardening in PartitionValidGptTable(), PartitionCheckGptEntry() and PartitionRestoreGptTable() against future regressions. These tests exercise the shared parser, not the specific fix itself. The new cases drive the parser with malformed GPT structures that an attacker may present: bad signature/revision, header-size boundaries, CRC corruption, MyLBA replay, zero/non-power-of-two entry sizes, LBA multiplication overflow, out-of-range and overlapping entries, and restore failure on write-protected media. The INF file header is updated to note the added malformed coverage. Signed-off-by: Richard Lyu <richard.lyu@suse.com>
This commit is contained in:
parent
77585e5004
commit
b1029265b1
2 changed files with 571 additions and 3 deletions
|
|
@ -3,7 +3,11 @@
|
|||
|
||||
These tests exercise PartitionValidGptTable(), PartitionCheckGptEntry()
|
||||
and PartitionRestoreGptTable() against an in-memory mock disk, covering
|
||||
their behavior on well-formed GPT structures.
|
||||
both well-formed GPT structures and malformed ones an attacker may
|
||||
present: bad signature/revision, header size
|
||||
boundaries, CRC corruption, MyLBA replay, zero/non-power-of-two entry
|
||||
sizes, LBA multiplication overflow, out-of-range and overlapping
|
||||
entries, and backup/primary restore behavior.
|
||||
|
||||
Copyright (c) 2026, SUSE LLC. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
|
@ -145,6 +149,421 @@ TestLargerPowerOfTwoEntrySizeIsAccepted (
|
|||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that a GPT header read failure is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestHeaderReadFailureIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (DISK_SECTORS + 10, &Header));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that an invalid GPT signature is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestInvalidSignatureIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
GetPrimaryHeader ()->Header.Signature = SIGNATURE_64 ('X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
|
||||
UpdateGptHeaderCrc (GetPrimaryHeader ());
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (PRIMARY_PART_HEADER_LBA, &Header));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that an invalid GPT revision is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestInvalidRevisionIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
STATIC CONST UINT32 BadRevisions[] = { 0x00000000, 0x00010001, 0x00020000, 0xFFFFFFFF };
|
||||
UINTN Index;
|
||||
|
||||
for (Index = 0; Index < ARRAY_SIZE (BadRevisions); Index++) {
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
GetPrimaryHeader ()->Header.Revision = BadRevisions[Index];
|
||||
UpdateGptHeaderCrc (GetPrimaryHeader ());
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (PRIMARY_PART_HEADER_LBA, &Header));
|
||||
}
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that a header size below the minimum is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestHeaderSizeBelowMinimumIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
GetPrimaryHeader ()->Header.HeaderSize = TEST_GPT_HEADER_MIN_SIZE - 1;
|
||||
GetPrimaryHeader ()->Header.CRC32 = 0;
|
||||
GetPrimaryHeader ()->Header.CRC32 = CalculateCrc32 (GetPrimaryHeader (), TEST_GPT_HEADER_MIN_SIZE - 1);
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (PRIMARY_PART_HEADER_LBA, &Header));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that a zero header size is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestZeroHeaderSizeIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
GetPrimaryHeader ()->Header.HeaderSize = 0;
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (PRIMARY_PART_HEADER_LBA, &Header));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that a header size beyond the block size is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestHeaderSizeBeyondBlockSizeIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
//
|
||||
// HeaderSize larger than the block that was read: the CRC check must
|
||||
// refuse to scan past the buffer instead of reading out of bounds.
|
||||
//
|
||||
GetPrimaryHeader ()->Header.HeaderSize = SECTOR_SIZE + 1;
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (PRIMARY_PART_HEADER_LBA, &Header));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that a corrupt header CRC is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestCorruptHeaderCrcIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
GetPrimaryHeader ()->Header.CRC32 ^= 0xFFFFFFFF;
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (PRIMARY_PART_HEADER_LBA, &Header));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that a MyLBA mismatch is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestMyLbaMismatchIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
//
|
||||
// A header claiming to live at a different LBA than the one it was read
|
||||
// from (e.g. a copied/replayed header) must be rejected.
|
||||
//
|
||||
GetPrimaryHeader ()->MyLBA = 5;
|
||||
UpdateGptHeaderCrc (GetPrimaryHeader ());
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (PRIMARY_PART_HEADER_LBA, &Header));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that a header reporting zero partition entries is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestZeroPartitionEntriesIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
GetPrimaryHeader ()->NumberOfPartitionEntries = 0;
|
||||
UpdateGptHeaderCrc (GetPrimaryHeader ());
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (PRIMARY_PART_HEADER_LBA, &Header));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that a partition entry size below 128 bytes is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestEntrySizeTooSmallIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
GetPrimaryHeader ()->SizeOfPartitionEntry = (UINT32)(sizeof (EFI_PARTITION_ENTRY) / 2);
|
||||
UpdateGptHeaderCrc (GetPrimaryHeader ());
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (PRIMARY_PART_HEADER_LBA, &Header));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that a zero partition entry size is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestZeroEntrySizeIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
//
|
||||
// Must be rejected by the size check before the later division by
|
||||
// SizeOfPartitionEntry (division by zero) can be reached.
|
||||
//
|
||||
GetPrimaryHeader ()->SizeOfPartitionEntry = 0;
|
||||
UpdateGptHeaderCrc (GetPrimaryHeader ());
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (PRIMARY_PART_HEADER_LBA, &Header));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that a non power-of-two partition entry size is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestNonPowerOfTwoEntrySizeIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
//
|
||||
// 192 is >= 128 but not 128 * 2^n.
|
||||
//
|
||||
GetPrimaryHeader ()->SizeOfPartitionEntry = 192;
|
||||
UpdateGptHeaderCrc (GetPrimaryHeader ());
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (PRIMARY_PART_HEADER_LBA, &Header));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that a PartitionEntryLBA causing multiplication overflow is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestEntryLbaMultiplicationOverflowIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
//
|
||||
// PartitionEntryLBA * BlockSize would wrap around UINT64. Must be rejected
|
||||
// before any read is attempted with the truncated offset.
|
||||
//
|
||||
GetPrimaryHeader ()->PartitionEntryLBA = MAX_UINT64;
|
||||
UpdateGptHeaderCrc (GetPrimaryHeader ());
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (PRIMARY_PART_HEADER_LBA, &Header));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that an entry array CRC mismatch is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestEntryArrayCrcMismatchIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
//
|
||||
// Flip one byte inside an unused entry slot without refreshing the
|
||||
// entry-array CRC32 recorded in the header.
|
||||
//
|
||||
GetDiskLba (PRIMARY_PART_HEADER_LBA + 1)[(2U * PARTITION_ENTRY_SIZE) + 7] ^= 0xA5;
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (PRIMARY_PART_HEADER_LBA, &Header));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that an entry array read failure is rejected.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestEntryArrayReadFailureIsRejected (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
//
|
||||
// Entry array placed so close to the end of the device that reading
|
||||
// NumberOfPartitionEntries * SizeOfPartitionEntry bytes runs off the disk.
|
||||
//
|
||||
GetPrimaryHeader ()->PartitionEntryLBA = LAST_LBA;
|
||||
UpdateGptHeaderCrc (GetPrimaryHeader ());
|
||||
|
||||
UT_ASSERT_FALSE (ValidateAt (PRIMARY_PART_HEADER_LBA, &Header));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// PartitionCheckGptEntry() tests
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -302,6 +721,108 @@ TestEntryStrideFollowsSizeOfPartitionEntry (
|
|||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that an inverted LBA range reports OutOfRange.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestInvertedLbaRangeReportsOutOfRange (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
EFI_PARTITION_ENTRY Entries[1];
|
||||
EFI_PARTITION_ENTRY_STATUS Status[1];
|
||||
|
||||
InitCheckEntryHeader (&Header, 1, sizeof (EFI_PARTITION_ENTRY));
|
||||
ZeroMem (Entries, sizeof (Entries));
|
||||
ZeroMem (Status, sizeof (Status));
|
||||
|
||||
FillPartitionEntry (&Entries[0], &mPartitionGuid1, 100, 50);
|
||||
|
||||
PartitionCheckGptEntry (&Header, Entries, Status);
|
||||
|
||||
UT_ASSERT_TRUE (Status[0].OutOfRange);
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that an entry outside the usable region reports OutOfRange.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestEntryOutsideUsableRegionReportsOutOfRange (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
EFI_PARTITION_ENTRY Entries[2];
|
||||
EFI_PARTITION_ENTRY_STATUS Status[2];
|
||||
|
||||
InitCheckEntryHeader (&Header, 2, sizeof (EFI_PARTITION_ENTRY));
|
||||
ZeroMem (Entries, sizeof (Entries));
|
||||
ZeroMem (Status, sizeof (Status));
|
||||
|
||||
//
|
||||
// Entry 0 starts before FirstUsableLBA; entry 1 ends after LastUsableLBA.
|
||||
//
|
||||
FillPartitionEntry (&Entries[0], &mPartitionGuid1, FIRST_USABLE_LBA - 1, 100);
|
||||
FillPartitionEntry (&Entries[1], &mPartitionGuid2, 150, 201);
|
||||
|
||||
PartitionCheckGptEntry (&Header, Entries, Status);
|
||||
|
||||
UT_ASSERT_TRUE (Status[0].OutOfRange);
|
||||
UT_ASSERT_TRUE (Status[1].OutOfRange);
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that overlapping partition entries report Overlap.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestOverlappingEntriesReportOverlap (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER Header;
|
||||
EFI_PARTITION_ENTRY Entries[3];
|
||||
EFI_PARTITION_ENTRY_STATUS Status[3];
|
||||
|
||||
InitCheckEntryHeader (&Header, 3, sizeof (EFI_PARTITION_ENTRY));
|
||||
ZeroMem (Entries, sizeof (Entries));
|
||||
ZeroMem (Status, sizeof (Status));
|
||||
|
||||
FillPartitionEntry (&Entries[0], &mPartitionGuid1, 40, 100);
|
||||
FillPartitionEntry (&Entries[1], &mPartitionGuid2, 90, 150);
|
||||
FillPartitionEntry (&Entries[2], &mPartitionGuid1, 160, 200);
|
||||
|
||||
PartitionCheckGptEntry (&Header, Entries, Status);
|
||||
|
||||
UT_ASSERT_TRUE (Status[0].Overlap);
|
||||
UT_ASSERT_TRUE (Status[1].Overlap);
|
||||
UT_ASSERT_FALSE (Status[2].Overlap);
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// PartitionRestoreGptTable() tests
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -385,6 +906,34 @@ TestRestoreBackupFromPrimary (
|
|||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify that a restore attempt fails on write-protected media.
|
||||
|
||||
@param[in] Context Unit test context.
|
||||
|
||||
@retval UNIT_TEST_PASSED The test passed.
|
||||
**/
|
||||
STATIC
|
||||
UNIT_TEST_STATUS
|
||||
EFIAPI
|
||||
TestRestoreFailsOnWriteProtectedMedia (
|
||||
IN UNIT_TEST_CONTEXT Context
|
||||
)
|
||||
{
|
||||
EFI_PARTITION_TABLE_HEADER PrimaryHeader;
|
||||
|
||||
SetupDiskWithValidPrimary ();
|
||||
|
||||
UT_ASSERT_TRUE (ValidateAt (PRIMARY_PART_HEADER_LBA, &PrimaryHeader));
|
||||
|
||||
mWriteProtected = TRUE;
|
||||
|
||||
UT_ASSERT_FALSE (PartitionRestoreGptTable (&mBlockIo, &mDiskIo, &PrimaryHeader));
|
||||
UT_ASSERT_FALSE (ValidateAt (LAST_LBA, &PrimaryHeader));
|
||||
|
||||
return UNIT_TEST_PASSED;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Test runner
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -433,14 +982,33 @@ UefiTestMain (
|
|||
AddTestCase (ValidSuite, "Valid backup header is accepted", "ValidBackup", TestValidBackupHeaderIsAccepted, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "Minimum (92-byte) header size is accepted", "MinHeaderSize", TestMinimumHeaderSizeIsAccepted, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "256-byte partition entry size is accepted", "EntrySize256", TestLargerPowerOfTwoEntrySizeIsAccepted, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "Header read failure is rejected", "HeaderReadFailure", TestHeaderReadFailureIsRejected, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "Invalid signature is rejected", "InvalidSignature", TestInvalidSignatureIsRejected, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "Invalid revision is rejected", "InvalidRevision", TestInvalidRevisionIsRejected, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "Header size below minimum is rejected", "HeaderSizeTooSmall", TestHeaderSizeBelowMinimumIsRejected, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "Zero header size is rejected", "ZeroHeaderSize", TestZeroHeaderSizeIsRejected, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "Header size beyond block size is rejected", "HeaderSizeBeyondBlock", TestHeaderSizeBeyondBlockSizeIsRejected, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "Corrupt header CRC is rejected", "CorruptHeaderCrc", TestCorruptHeaderCrcIsRejected, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "MyLBA mismatch is rejected", "MyLbaMismatch", TestMyLbaMismatchIsRejected, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "Zero partition entries is rejected", "ZeroEntries", TestZeroPartitionEntriesIsRejected, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "Entry size below 128 is rejected", "EntrySizeTooSmall", TestEntrySizeTooSmallIsRejected, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "Zero entry size is rejected", "ZeroEntrySize", TestZeroEntrySizeIsRejected, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "Non power-of-two entry size is rejected", "NonPowerOfTwoEntrySize", TestNonPowerOfTwoEntrySizeIsRejected, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "PartitionEntryLBA overflow is rejected", "EntryLbaOverflow", TestEntryLbaMultiplicationOverflowIsRejected, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "Entry array CRC mismatch is rejected", "EntryArrayCrcMismatch", TestEntryArrayCrcMismatchIsRejected, NULL, NULL, NULL);
|
||||
AddTestCase (ValidSuite, "Entry array read failure is rejected", "EntryArrayReadFailure", TestEntryArrayReadFailureIsRejected, NULL, NULL, NULL);
|
||||
|
||||
AddTestCase (EntrySuite, "Valid entries report no flags", "ValidEntries", TestValidEntriesReportNoFlags, NULL, NULL, NULL);
|
||||
AddTestCase (EntrySuite, "OS-specific attribute is reported", "OsSpecificAttribute", TestOsSpecificAttributeIsReported, NULL, NULL, NULL);
|
||||
AddTestCase (EntrySuite, "Unused entries are ignored", "UnusedEntriesIgnored", TestUnusedEntriesAreIgnored, NULL, NULL, NULL);
|
||||
AddTestCase (EntrySuite, "Entry stride follows SizeOfPartitionEntry", "EntryStride", TestEntryStrideFollowsSizeOfPartitionEntry, NULL, NULL, NULL);
|
||||
AddTestCase (EntrySuite, "Inverted LBA range reports OutOfRange", "InvertedRange", TestInvertedLbaRangeReportsOutOfRange, NULL, NULL, NULL);
|
||||
AddTestCase (EntrySuite, "Entry outside usable region reports OutOfRange", "OutsideUsableRegion", TestEntryOutsideUsableRegionReportsOutOfRange, NULL, NULL, NULL);
|
||||
AddTestCase (EntrySuite, "Overlapping entries report Overlap", "OverlappingEntries", TestOverlappingEntriesReportOverlap, NULL, NULL, NULL);
|
||||
|
||||
AddTestCase (RestoreSuite, "Restore primary from backup", "RestorePrimary", TestRestorePrimaryFromBackup, NULL, NULL, NULL);
|
||||
AddTestCase (RestoreSuite, "Restore backup from primary", "RestoreBackup", TestRestoreBackupFromPrimary, NULL, NULL, NULL);
|
||||
AddTestCase (RestoreSuite, "Restore fails on write-protected media", "RestoreWriteProtected", TestRestoreFailsOnWriteProtectedMedia, NULL, NULL, NULL);
|
||||
|
||||
Status = RunAllTestSuites (Framework);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
# Host-based unit tests for GptLib.
|
||||
#
|
||||
# Exercises PartitionValidGptTable(), PartitionCheckGptEntry() and
|
||||
# PartitionRestoreGptTable() against an in-memory mock disk, covering their
|
||||
# behavior on well-formed GPT structures.
|
||||
# PartitionRestoreGptTable() against an in-memory mock disk, covering both
|
||||
# well-formed GPT structures and malformed ones an attacker may present.
|
||||
#
|
||||
# Copyright (c) 2026, SUSE LLC. All rights reserved.<BR>
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue