From 02c39b43890c9c891d9b6397a8901c42db4e9f0e Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Sun, 17 Nov 2024 15:19:26 -0500 Subject: [PATCH] gptfixer: do not look at start or end of unused partitions They have undefined values, though in practice they are generally zero. --- gptfixer/gpt.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/gptfixer/gpt.c b/gptfixer/gpt.c index ec305fcd..48d9c286 100644 --- a/gptfixer/gpt.c +++ b/gptfixer/gpt.c @@ -180,11 +180,10 @@ static bool check_mbr(struct Mbr *mbr, uint64_t size_in_sectors) { return changed; } -struct GPT { - struct GPTHeader header; - uint32_t used_entries; - struct GPTPartitionEntry *entries; -}; +static bool unused_entry(const struct GPTPartitionEntry *const entry) { + const char zero[sizeof(entry->PartitionTypeGUID)] = {0}; + return memcmp(zero, &entry->PartitionTypeGUID, sizeof(zero)) == 0; +} #define for_each_gpt_entry(i, size, count, gpt, entry) \ if ((gpt)->header.SizeOfPartitionEntry < sizeof(struct GPTPartitionEntry) || \ @@ -242,6 +241,9 @@ static struct GPT *gpt_grow_sectors(uint64_t sector_offset, uint32_t partition_that_starts_first = UINT32_MAX; uint32_t partition_that_ends_last = UINT32_MAX; for_each_gpt_entry(i, size, count, gpt, entry) { + if (unused_entry(entry)) { + continue; + } uint64_t start_byte_offset = entry->StartingLBA * old_sector_size; uint64_t end_byte_offset = (entry->EndingLBA + 1) * old_sector_size; vlog("Partition consumes bytes [0x%" PRIX64 ", 0x%" PRIX64 ")", @@ -325,8 +327,10 @@ static struct GPT *gpt_grow_sectors(uint64_t sector_offset, struct GPTPartitionEntry *new_entry = (struct GPTPartitionEntry *)((char *)new_gpt->entries + i * size); memcpy(new_entry, entry, sizeof(*entry)); - new_entry->EndingLBA = ((entry->EndingLBA + 1) / sector_ratio) - 1; - new_entry->StartingLBA /= sector_ratio; + if (!unused_entry(entry)) { + new_entry->EndingLBA = ((entry->EndingLBA + 1) / sector_ratio) - 1; + new_entry->StartingLBA /= sector_ratio; + } } *allocated = bytes_required; fixup_gpt(new_gpt, bytes_required); @@ -389,8 +393,10 @@ struct GPT *gpt_shrink_sectors(uint64_t sector_offset, uint32_t sector_size, struct GPTPartitionEntry *new_entry = (struct GPTPartitionEntry *)((char *)new_gpt->entries + i * size); memcpy(new_entry, entry, size); - new_entry->EndingLBA = ((entry->EndingLBA + 1) * sector_ratio) - 1; - new_entry->StartingLBA *= sector_ratio; + if (!unused_entry(entry)) { + new_entry->EndingLBA = ((entry->EndingLBA + 1) * sector_ratio) - 1; + new_entry->StartingLBA *= sector_ratio; + } } fixup_gpt(new_gpt, (uint32_t)bytes_required); assert(new_gpt->entries); @@ -636,9 +642,7 @@ static struct GPT *read_and_check_gpt(int fd, uint64_t sector_offset, uint32_t used_entries = 0; gpt->used_entries = partition_entry_count; for_each_gpt_entry(i, size, count, gpt, entry) { - const char zero[sizeof(entry->PartitionTypeGUID)] = {0}; - if (memcmp(zero, &entry->PartitionTypeGUID, sizeof(zero)) == 0) { - // Unused entry + if (unused_entry(entry)) { continue; } if (entry->StartingLBA < header->FirstUsableLBA) { @@ -699,6 +703,9 @@ static void print_gpts(struct GPT *gpt) { header->PartitionEntryLBA, header->NumberOfPartitionEntries, header->SizeOfPartitionEntry, header->PartitionEntryArrayCRC32); for_each_gpt_entry(i, size, count, gpt, entry) { + if (unused_entry(entry)) { + continue; + } fprintf( stdout, "GPT Partition Table Entry:\n"