grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 7/7] gpt: respect native sector size if set/detected


From: Mihai Moldovan
Subject: [PATCH 7/7] gpt: respect native sector size if set/detected
Date: Sun, 24 May 2020 13:43:08 +0200

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..51d752522 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 value different from the
+       * default/internal one, it means that *something* autodetected the
+       * native sector size and we don't have to and 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]