From aa8eda4f97f43a51bfec4fc096635565617a89e0 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Fri, 27 Aug 2010 09:31:26 -0700 Subject: [PATCH] More cgptlib tests Add some extra cases to SanityCheckTest() to test both header and entries being garbled at either end of the disk. Add DuplicateUniqueGuidTest() to check that GPTs having duplicate UniqueGuids in the entries are rejected. We can only check this per-disk, of course. Made some changes to the library to enforce the UniqueGuid requirement that I just started testing for. BUG=chromium-os:4854 Review URL: http://codereview.chromium.org/3135044 Change-Id: I86458faf9cc99aa3f29aac0d5b144dbd05067181 --- firmware/lib/cgptlib/cgptlib_internal.c | 4 + firmware/version.c | 2 +- tests/cgptlib_test.c | 98 +++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) diff --git a/firmware/lib/cgptlib/cgptlib_internal.c b/firmware/lib/cgptlib/cgptlib_internal.c index a0c1688649..ee3c87f183 100644 --- a/firmware/lib/cgptlib/cgptlib_internal.c +++ b/firmware/lib/cgptlib/cgptlib_internal.c @@ -152,6 +152,10 @@ int CheckEntries(GptEntry* entries, GptHeader* h) { if ((entry->ending_lba >= e2->starting_lba) && (entry->ending_lba <= e2->ending_lba)) return 1; + + /* UniqueGuid field must be unique. */ + if (0 == Memcmp(&entry->unique, &e2->unique, sizeof(Guid))) + return 1; } } diff --git a/firmware/version.c b/firmware/version.c index 73f10a5f3b..0ecee87b51 100644 --- a/firmware/version.c +++ b/firmware/version.c @@ -1 +1 @@ -char* VbootVersion = "VBOOv=8dd12638"; +char* VbootVersion = "VBOOv=c58c9bc8"; diff --git a/tests/cgptlib_test.c b/tests/cgptlib_test.c index 5b0b9b4751..891d53b72a 100644 --- a/tests/cgptlib_test.c +++ b/tests/cgptlib_test.c @@ -45,6 +45,13 @@ static const Guid guid_zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}}; static const Guid guid_kernel = GPT_ENT_TYPE_CHROMEOS_KERNEL; static const Guid guid_rootfs = GPT_ENT_TYPE_CHROMEOS_ROOTFS; +/* Copy a random-for-this-program-only Guid into the dest. The num parameter + * completely determines the Guid. + */ +static void SetGuid(void *dest, uint32_t num) { + Guid g = {{{num,0xd450,0x44bc,0xa6,0x93,{0xb8,0xac,0x75,0x5f,0xcd,0x48}}}}; + Memcpy(dest, &g, sizeof(Guid)); +} /* Given a GptData pointer, first re-calculate entries CRC32 value, * then reset header CRC32 value to 0, and calculate header CRC32 value. @@ -147,15 +154,19 @@ static void BuildTestGptData(GptData* gpt) { header->number_of_entries = 128; /* 512B / 128B * 32sectors = 128 entries */ header->size_of_entry = 128; /* bytes */ Memcpy(&entries[0].type, &chromeos_kernel, sizeof(chromeos_kernel)); + SetGuid(&entries[0].unique, 0); entries[0].starting_lba = 34; entries[0].ending_lba = 133; Memcpy(&entries[1].type, &chromeos_rootfs, sizeof(chromeos_rootfs)); + SetGuid(&entries[1].unique, 1); entries[1].starting_lba = 134; entries[1].ending_lba = 232; Memcpy(&entries[2].type, &chromeos_rootfs, sizeof(chromeos_rootfs)); + SetGuid(&entries[2].unique, 2); entries[2].starting_lba = 234; entries[2].ending_lba = 331; Memcpy(&entries[3].type, &chromeos_kernel, sizeof(chromeos_kernel)); + SetGuid(&entries[3].unique, 3); entries[3].starting_lba = 334; entries[3].ending_lba = 430; @@ -663,6 +674,7 @@ static int OverlappedPartitionTest() { if (cases[i].entries[j].active) Memcpy(&e[j].type, &guid_kernel, sizeof(Guid)); + SetGuid(&e[j].unique, j); e[j].starting_lba = cases[i].entries[j].starting_lba; e[j].ending_lba = cases[i].entries[j].ending_lba; } @@ -777,6 +789,31 @@ static int SanityCheckTest() { EXPECT(MASK_BOTH == gpt->valid_entries); EXPECT(GPT_MODIFIED_ENTRIES2 == gpt->modified); + /* Modify both header and entries */ + BuildTestGptData(gpt); + gpt->primary_header[0]++; + gpt->primary_entries[0]++; + EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); + EXPECT(MASK_SECONDARY == gpt->valid_headers); + EXPECT(MASK_SECONDARY == gpt->valid_entries); + GptRepair(gpt); + EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); + EXPECT(MASK_BOTH == gpt->valid_headers); + EXPECT(MASK_BOTH == gpt->valid_entries); + EXPECT((GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1) == gpt->modified); + + BuildTestGptData(gpt); + gpt->secondary_header[0]++; + gpt->secondary_entries[0]++; + EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); + EXPECT(MASK_PRIMARY == gpt->valid_headers); + EXPECT(MASK_PRIMARY == gpt->valid_entries); + GptRepair(gpt); + EXPECT(GPT_SUCCESS == GptSanityCheck(gpt)); + EXPECT(MASK_BOTH == gpt->valid_headers); + EXPECT(MASK_BOTH == gpt->valid_entries); + EXPECT((GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2) == gpt->modified); + /* Test cross-correction (h1+e2, h2+e1) */ BuildTestGptData(gpt); gpt->primary_header[0]++; @@ -1092,6 +1129,66 @@ static int UpdateInvalidKernelTypeTest() { return TEST_OK; } + +/* Tests duplicate UniqueGuids can be detected. */ +static int DuplicateUniqueGuidTest() { + GptData* gpt = GetEmptyGptData(); + GptHeader* h = (GptHeader*)gpt->primary_header; + GptEntry* e = (GptEntry*)gpt->primary_entries; + int i, j; + + struct { + int duplicate; + struct { + uint64_t starting_lba; + uint64_t ending_lba; + uint32_t type_guid; + uint32_t unique_guid; + } entries[16]; /* enough for testing. */ + } cases[] = { + {0, {{100, 109, 1, 1}, + {110, 119, 2, 2}, + {120, 129, 3, 3}, + {130, 139, 4, 4}, + }}, + {0, {{100, 109, 1, 1}, + {110, 119, 1, 2}, + {120, 129, 2, 3}, + {130, 139, 2, 4}, + }}, + {1, {{100, 109, 1, 1}, + {110, 119, 2, 2}, + {120, 129, 3, 1}, + {130, 139, 4, 4}, + }}, + {1, {{100, 109, 1, 1}, + {110, 119, 1, 2}, + {120, 129, 2, 3}, + {130, 139, 2, 2}, + }}, + }; + + for (i = 0; i < ARRAY_SIZE(cases); ++i) { + BuildTestGptData(gpt); + ZeroEntries(gpt); + for(j = 0; j < ARRAY_SIZE(cases[0].entries); ++j) { + if (!cases[i].entries[j].starting_lba) + break; + + e[j].starting_lba = cases[i].entries[j].starting_lba; + e[j].ending_lba = cases[i].entries[j].ending_lba; + SetGuid(&e[j].type, cases[i].entries[j].type_guid); + SetGuid(&e[j].unique, cases[i].entries[j].unique_guid); + } + RefreshCrc32(gpt); + + EXPECT(cases[i].duplicate == CheckEntries(e, h)); + } + return TEST_OK; +} + + + /* disable MSVC warnings on unused arguments */ __pragma(warning (disable: 4100)) @@ -1128,6 +1225,7 @@ int main(int argc, char *argv[]) { { TEST_CASE(GetNextTriesTest), }, { TEST_CASE(GptUpdateTest), }, { TEST_CASE(UpdateInvalidKernelTypeTest), }, + { TEST_CASE(DuplicateUniqueGuidTest), }, { TEST_CASE(TestCrc32TestVectors), }, };