]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2009-09-15 Vladimir Serbinenko <phcoder@gmail.com>
authorphcoder <phcoder@localhost>
Tue, 15 Sep 2009 10:36:29 +0000 (10:36 +0000)
committerphcoder <phcoder@localhost>
Tue, 15 Sep 2009 10:36:29 +0000 (10:36 +0000)
* partmap/pc.c (pc_partition_map_iterate): Detect and break loops.

ChangeLog
partmap/msdos.c

index 2d1733ac3ea496b477f820ab7b1e3bf052fd8735..be7715f252fba6046576d80d84a662de53cf0a68 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2009-09-15  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       * partmap/pc.c (pc_partition_map_iterate): Detect and break loops.
+
 2009-09-14  Colin Watson  <cjwatson@ubuntu.com>
 
        * commands/test.c (get_fileinfo): Return immediately if
index d0fc18efedb6be65e5f925e97b7bd90c502465d9..a5d55b64d2b4ffccfd43d012b30d90c27b55d616 100644 (file)
@@ -97,6 +97,8 @@ pc_partition_map_iterate (grub_disk_t disk,
   struct grub_msdos_partition_mbr mbr;
   struct grub_msdos_partition_disk_label label;
   struct grub_disk raw;
+  int labeln = 0;
+  grub_disk_addr_t lastaddr;
 
   /* Enforce raw disk access.  */
   raw = *disk;
@@ -117,6 +119,18 @@ pc_partition_map_iterate (grub_disk_t disk,
       if (grub_disk_read (&raw, p.offset, 0, sizeof (mbr), &mbr))
        goto finish;
 
+      /* This is our loop-detection algorithm. It works the following way:
+        It saves last position which was a power of two. Then it compares the
+        saved value with a current one. This way it's guaranteed that the loop
+        will be broken by at most third walk.
+       */
+      if (labeln && lastaddr == p.offset)
+       return grub_error (GRUB_ERR_BAD_PART_TABLE, "loop detected");
+
+      labeln++;
+      if ((labeln & (labeln - 1)) == 0)
+       lastaddr = p.offset;
+
       /* Check if it is valid.  */
       if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE))
        return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");