The GPT parsing code includes some autodetection magic for non-default sector sizes.
This is working fine if the underlaying disk abstraction uses the default sector size of 512 bytes, but will return wrong information (and read invalid data!) if it is not. Fix this by skipping the sector size autodetection if the disk's sector size is not the default one and trust it to be correct for subsequent sector calculations. --- grub-core/partmap/gpt.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c index 4b968529a..38721275f 100644 --- a/grub-core/partmap/gpt.c +++ b/grub-core/partmap/gpt.c @@ -58,7 +58,7 @@ grub_gpt_partition_map_iterate (grub_disk_t disk, grub_uint64_t entries; unsigned int i; int last_offset = 0; - int sector_log = 0; + unsigned int sector_log = 0; /* Read the protective MBR. */ if (grub_disk_read (disk, 0, 0, sizeof (mbr), &mbr)) @@ -76,16 +76,39 @@ grub_gpt_partition_map_iterate (grub_disk_t disk, return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found"); /* Read the GPT header. */ - for (sector_log = 0; sector_log < MAX_SECTOR_LOG; sector_log++) + if (disk->log_sector_size > GRUB_DISK_SECTOR_BITS) { + /* + * If the disk sector size has been set to a value different from the + * default/internal one, it means that *something* autodetected the + * native sector size, we don't have to and also shouldn't try to use a + * sector size heuristic. + */ + sector_log = disk->log_sector_size - GRUB_DISK_SECTOR_BITS; + if (grub_disk_read (disk, 1 << sector_log, 0, sizeof (gpt), &gpt)) return grub_errno; - if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic)) == 0) - break; + if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic)) != 0) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no valid GPT header"); + } + else + { + /* + * Otherwise, the native sector size might be wrong, so try to + * autodetect. + */ + for (sector_log = 0; sector_log < MAX_SECTOR_LOG; sector_log++) + { + if (grub_disk_read (disk, 1 << sector_log, 0, sizeof (gpt), &gpt)) + return grub_errno; + + if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic)) == 0) + break; + } + if (sector_log == MAX_SECTOR_LOG) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no valid GPT header"); } - if (sector_log == MAX_SECTOR_LOG) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "no valid GPT header"); grub_dprintf ("gpt", "Read a valid GPT header\n"); -- 2.25.1 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel