diff options
Diffstat (limited to 'firmware/lib/cgptlib/cgptlib_internal.c')
-rw-r--r-- | firmware/lib/cgptlib/cgptlib_internal.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/firmware/lib/cgptlib/cgptlib_internal.c b/firmware/lib/cgptlib/cgptlib_internal.c index 4eea03df..e9f27c96 100644 --- a/firmware/lib/cgptlib/cgptlib_internal.c +++ b/firmware/lib/cgptlib/cgptlib_internal.c @@ -20,6 +20,16 @@ int CheckParameters(GptData *gpt) return GPT_ERROR_INVALID_SECTOR_SIZE; /* + * gpt_drive_sectors should be reasonable. It cannot be unset, and it cannot + * differ from drive_sectors if the GPT structs are stored on same device. + */ + if (gpt->gpt_drive_sectors == 0 || + (gpt->stored_on_device == GPT_STORED_ON_DEVICE && + gpt->gpt_drive_sectors != gpt->drive_sectors)) { + return GPT_ERROR_INVALID_SECTOR_NUMBER; + } + + /* * 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. @@ -43,7 +53,8 @@ uint32_t HeaderCrc(GptHeader *h) return crc32; } -int CheckHeader(GptHeader *h, int is_secondary, uint64_t drive_sectors) +int CheckHeader(GptHeader *h, int is_secondary, uint64_t drive_sectors, + uint8_t stored_on_device) { if (!h) return 1; @@ -80,7 +91,8 @@ int CheckHeader(GptHeader *h, int is_secondary, uint64_t drive_sectors) return 1; if ((h->number_of_entries < MIN_NUMBER_OF_ENTRIES) || (h->number_of_entries > MAX_NUMBER_OF_ENTRIES) || - (h->number_of_entries * h->size_of_entry != TOTAL_ENTRIES_SIZE)) + (stored_on_device == GPT_STORED_ON_DEVICE && + h->number_of_entries * h->size_of_entry != TOTAL_ENTRIES_SIZE)) return 1; /* @@ -100,18 +112,27 @@ int CheckHeader(GptHeader *h, int is_secondary, uint64_t drive_sectors) return 1; } + /* FirstUsableLBA <= LastUsableLBA. */ + if (h->first_usable_lba > h->last_usable_lba) + return 1; + + if (stored_on_device != GPT_STORED_ON_DEVICE) { + if (h->last_usable_lba >= drive_sectors) { + return 1; + } + return 0; + } + /* * FirstUsableLBA must be after the end of the primary GPT table array. * LastUsableLBA must be before the start of the secondary GPT table - * array. FirstUsableLBA <= LastUsableLBA. + * array. */ /* TODO(namnguyen): Also check for padding between header & entries. */ if (h->first_usable_lba < 2 + GPT_ENTRIES_SECTORS) return 1; if (h->last_usable_lba >= drive_sectors - 1 - GPT_ENTRIES_SECTORS) return 1; - if (h->first_usable_lba > h->last_usable_lba) - return 1; /* Success */ return 0; @@ -224,11 +245,11 @@ int GptSanityCheck(GptData *gpt) return retval; /* Check both headers; we need at least one valid header. */ - if (0 == CheckHeader(header1, 0, gpt->drive_sectors)) { + if (0 == CheckHeader(header1, 0, gpt->drive_sectors, gpt->stored_on_device)) { gpt->valid_headers |= MASK_PRIMARY; goodhdr = header1; } - if (0 == CheckHeader(header2, 1, gpt->drive_sectors)) { + if (0 == CheckHeader(header2, 1, gpt->drive_sectors, gpt->stored_on_device)) { gpt->valid_headers |= MASK_SECONDARY; if (!goodhdr) goodhdr = header2; |