2009-09-15 Vladimir Serbinenko <phcoder@gmail.com>

* partmap/pc.c (pc_partition_map_iterate): Detect and break loops.
This commit is contained in:
phcoder 2009-09-15 10:36:29 +00:00
parent 07197f2322
commit 77c24f1dc5
2 changed files with 18 additions and 0 deletions

View File

@ -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

View 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");