diff --git a/cgpt/cgpt_create.c b/cgpt/cgpt_create.c index 60e23c9630..c34cfe31e8 100644 --- a/cgpt/cgpt_create.c +++ b/cgpt/cgpt_create.c @@ -48,7 +48,7 @@ static int GptCreate(struct drive *drive, CgptCreateParams *params) { /* Calculate number of entries */ h->size_of_entry = sizeof(GptEntry); - h->number_of_entries = TOTAL_ENTRIES_SIZE / h->size_of_entry; + h->number_of_entries = MAX_NUMBER_OF_ENTRIES; if (drive->gpt.flags & GPT_FLAG_EXTERNAL) { // We might have smaller space for the GPT table. Scale accordingly. // diff --git a/firmware/include/gpt_misc.h b/firmware/include/gpt_misc.h index 0618069603..f48133a05d 100644 --- a/firmware/include/gpt_misc.h +++ b/firmware/include/gpt_misc.h @@ -34,12 +34,6 @@ enum { #define GPT_MODIFIED_ENTRIES1 0x04 #define GPT_MODIFIED_ENTRIES2 0x08 -/* - * Size of GptData.primary_entries and secondary_entries: 128 bytes/entry * 128 - * entries. - */ -#define TOTAL_ENTRIES_SIZE 16384 - /* * The 'update_type' of GptUpdateKernelEntry(). We expose TRY and BAD only * because those are what verified boot needs. For more precise control on GPT diff --git a/firmware/lib/cgptlib/cgptlib_internal.c b/firmware/lib/cgptlib/cgptlib_internal.c index 6a89d84128..a389e695ce 100644 --- a/firmware/lib/cgptlib/cgptlib_internal.c +++ b/firmware/lib/cgptlib/cgptlib_internal.c @@ -40,11 +40,11 @@ int CheckParameters(GptData *gpt) /* * Sector count of a drive should be reasonable. If the given value is * too small to contain basic GPT structure (PMBR + Headers + Entries), - * the value is wrong. Entries size is hard coded to TOTAL_ENTRIES_SIZE (see - * cgpt_create.c). This check is only applicable when GPT is stored on device. + * the value is wrong. */ - if (!(gpt->flags & GPT_FLAG_EXTERNAL) && - gpt->gpt_drive_sectors < (1 + 2 * (1 + TOTAL_ENTRIES_SIZE / SECTOR_SIZE))) + if (gpt->gpt_drive_sectors < + (1 + 2 * (1 + MIN_NUMBER_OF_ENTRIES / + (SECTOR_SIZE / sizeof(GptEntry))))) return GPT_ERROR_INVALID_SECTOR_NUMBER; return GPT_SUCCESS; @@ -103,7 +103,7 @@ int CheckHeader(GptHeader *h, int is_secondary, if ((h->number_of_entries < MIN_NUMBER_OF_ENTRIES) || (h->number_of_entries > MAX_NUMBER_OF_ENTRIES) || (!(flags & GPT_FLAG_EXTERNAL) && - h->number_of_entries * h->size_of_entry != TOTAL_ENTRIES_SIZE)) + h->number_of_entries != MAX_NUMBER_OF_ENTRIES)) return 1; /* diff --git a/firmware/lib/cgptlib/include/cgptlib_internal.h b/firmware/lib/cgptlib/include/cgptlib_internal.h index b4e2f5f9e3..0be2bc5ac9 100644 --- a/firmware/lib/cgptlib/include/cgptlib_internal.h +++ b/firmware/lib/cgptlib/include/cgptlib_internal.h @@ -52,7 +52,7 @@ #define MAX_SIZE_OF_ENTRY 512 #define SIZE_OF_ENTRY_MULTIPLE 8 #define MIN_NUMBER_OF_ENTRIES 16 -#define MAX_NUMBER_OF_ENTRIES 512 +#define MAX_NUMBER_OF_ENTRIES 128 /* Defines GPT sizes */ #define GPT_PMBR_SECTORS 1 /* size (in sectors) of PMBR */ diff --git a/firmware/lib/gpt_misc.c b/firmware/lib/gpt_misc.c index c16d47299f..00c7f9f260 100644 --- a/firmware/lib/gpt_misc.c +++ b/firmware/lib/gpt_misc.c @@ -23,7 +23,7 @@ */ int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata) { - uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes; + uint64_t max_entries_bytes = MAX_NUMBER_OF_ENTRIES * sizeof(GptEntry); int primary_valid = 0, secondary_valid = 0; /* No data to be written yet */ @@ -33,8 +33,8 @@ int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata) gptdata->primary_header = (uint8_t *)VbExMalloc(gptdata->sector_bytes); gptdata->secondary_header = (uint8_t *)VbExMalloc(gptdata->sector_bytes); - gptdata->primary_entries = (uint8_t *)VbExMalloc(TOTAL_ENTRIES_SIZE); - gptdata->secondary_entries = (uint8_t *)VbExMalloc(TOTAL_ENTRIES_SIZE); + gptdata->primary_entries = (uint8_t *)VbExMalloc(max_entries_bytes); + gptdata->secondary_entries = (uint8_t *)VbExMalloc(max_entries_bytes); if (gptdata->primary_header == NULL || gptdata->secondary_header == NULL || @@ -53,6 +53,10 @@ int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata) gptdata->gpt_drive_sectors, gptdata->flags)) { primary_valid = 1; + uint64_t entries_bytes = primary_header->number_of_entries + * primary_header->size_of_entry; + uint64_t entries_sectors = entries_bytes + / gptdata->sector_bytes; if (0 != VbExDiskRead(disk_handle, primary_header->entries_lba, entries_sectors, @@ -74,6 +78,10 @@ int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata) gptdata->gpt_drive_sectors, gptdata->flags)) { secondary_valid = 1; + uint64_t entries_bytes = secondary_header->number_of_entries + * secondary_header->size_of_entry; + uint64_t entries_sectors = entries_bytes + / gptdata->sector_bytes; if (0 != VbExDiskRead(disk_handle, secondary_header->entries_lba, entries_sectors, @@ -95,7 +103,10 @@ int AllocAndReadGptData(VbExDiskHandle_t disk_handle, GptData *gptdata) int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata) { int legacy = 0; - uint64_t entries_sectors = TOTAL_ENTRIES_SIZE / gptdata->sector_bytes; + GptHeader *header = (GptHeader *)gptdata->primary_header; + uint64_t entries_bytes = header->number_of_entries + * header->size_of_entry; + uint64_t entries_sectors = entries_bytes / gptdata->sector_bytes; int ret = 1; /* diff --git a/tests/cgptlib_test.c b/tests/cgptlib_test.c index 759fa500eb..13244a5654 100644 --- a/tests/cgptlib_test.c +++ b/tests/cgptlib_test.c @@ -42,6 +42,7 @@ #define DEFAULT_SECTOR_SIZE 512 #define MAX_SECTOR_SIZE 4096 #define DEFAULT_DRIVE_SECTORS 467 +#define TOTAL_ENTRIES_SIZE (MAX_NUMBER_OF_ENTRIES * sizeof(GptEntry)) /* 16384 */ #define PARTITION_ENTRIES_SIZE TOTAL_ENTRIES_SIZE /* 16384 */ static const Guid guid_zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}}; @@ -245,7 +246,7 @@ static int ParameterTests(void) {512, DEFAULT_DRIVE_SECTORS, GPT_SUCCESS}, {520, DEFAULT_DRIVE_SECTORS, GPT_ERROR_INVALID_SECTOR_SIZE}, {512, 0, GPT_ERROR_INVALID_SECTOR_NUMBER}, - {512, 66, GPT_ERROR_INVALID_SECTOR_NUMBER}, + {512, 10, GPT_ERROR_INVALID_SECTOR_NUMBER}, {512, GPT_PMBR_SECTORS + GPT_HEADER_SECTORS * 2 + TOTAL_ENTRIES_SIZE / DEFAULT_SECTOR_SIZE * 2, GPT_SUCCESS}, {4096, DEFAULT_DRIVE_SECTORS, GPT_ERROR_INVALID_SECTOR_SIZE}, diff --git a/tests/vboot_kernel_tests.c b/tests/vboot_kernel_tests.c index e19ac114d5..03e77f9878 100644 --- a/tests/vboot_kernel_tests.c +++ b/tests/vboot_kernel_tests.c @@ -83,7 +83,7 @@ static void SetupGptHeader(GptHeader *h, int is_secondary) /* 16KB: 128 entries of 128 bytes */ h->size_of_entry = sizeof(GptEntry); - h->number_of_entries = TOTAL_ENTRIES_SIZE / h->size_of_entry; + h->number_of_entries = MAX_NUMBER_OF_ENTRIES; /* Set LBA pointers for primary or secondary header */ if (is_secondary) { @@ -429,6 +429,8 @@ static void ReadWriteGptTest(void) Memset(g.primary_header, '\0', g.sector_bytes); h = (GptHeader*)g.primary_header; h->entries_lba = 2; + h->number_of_entries = MAX_NUMBER_OF_ENTRIES; + h->size_of_entry = sizeof(GptEntry); TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod 1"); TEST_CALLS("VbExDiskWrite(h, 1, 1)\n" "VbExDiskWrite(h, 2, 32)\n"); @@ -441,6 +443,8 @@ static void ReadWriteGptTest(void) Memset(g.primary_header, '\0', g.sector_bytes); h = (GptHeader*)g.primary_header; h->entries_lba = 2; + h->number_of_entries = MAX_NUMBER_OF_ENTRIES; + h->size_of_entry = sizeof(GptEntry); h = (GptHeader*)g.secondary_header; h->entries_lba = 991; TEST_EQ(WriteAndFreeGptData(handle, &g), 0, "WriteAndFree mod all");