2009-09-15 Vladimir Serbinenko <phcoder@gmail.com>
* partmap/pc.c (pc_partition_map_iterate): Detect and break loops.
This commit is contained in:
parent
07197f2322
commit
77c24f1dc5
2 changed files with 18 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue