--- grub_trunk/kern/partition.c 2010-05-28 01:50:37.000000000 +0200
+++ grub_trunk_new/kern/partition.c 2010-05-28 01:53:13.000000000 +0200
@@ -16,32 +16,50 @@
* along with GRUB. If not, see .
*/
#include
#include
#include
#include
grub_partition_map_t grub_partition_map_list;
+/*
+ * Checks that a partition is contained in its parent.
+ */
+static int
+grub_partition_validate (const grub_disk_t disk,
+ const grub_partition_t partition)
+{
+ grub_disk_addr_t parent_len;
+
+ if (disk->partition)
+ parent_len = grub_partition_get_len (disk->partition);
+ else
+ parent_len = disk->total_sectors;
+
+ return (partition->start + partition->len <= parent_len);
+}
+
static grub_partition_t
grub_partition_map_probe (const grub_partition_map_t partmap,
grub_disk_t disk, int partnum)
{
grub_partition_t p = 0;
auto int find_func (grub_disk_t d, const grub_partition_t partition);
- int find_func (grub_disk_t d __attribute__ ((unused)),
+ int find_func (grub_disk_t dsk,
const grub_partition_t partition)
{
- if (partnum == partition->number)
+ if (partnum == partition->number &&
+ grub_partition_validate (dsk, partition))
{
p = (grub_partition_t) grub_malloc (sizeof (*p));
if (! p)
return 1;
grub_memcpy (p, partition, sizeof (*p));
return 1;
}
return 0;
@@ -131,20 +149,24 @@ grub_partition_iterate (struct grub_disk
const grub_partition_t partition))
{
int ret = 0;
auto int part_iterate (grub_disk_t dsk, const grub_partition_t p);
int part_iterate (grub_disk_t dsk,
const grub_partition_t partition)
{
struct grub_partition p = *partition;
+
+ if (!(grub_partition_validate (dsk, partition)))
+ return 0;
+
p.parent = dsk->partition;
dsk->partition = 0;
if (hook (dsk, &p))
{
ret = 1;
return 1;
}
if (p.start != 0)
{
const struct grub_partition_map *partmap;
--- grub_trunk/partmap/bsdlabel.c 2010-05-28 01:50:39.000000000 +0200
+++ grub_trunk_new/partmap/bsdlabel.c 2010-05-28 02:10:26.000000000 +0200
@@ -47,39 +47,46 @@ bsdlabel_partition_map_iterate (grub_dis
/* Check if it is valid. */
if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC))
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR
* GRUB_DISK_SECTOR_SIZE;
for (p.number = 0;
p.number < grub_cpu_to_le16 (label.num_partitions);
- p.number++)
+ p.number++, pos += sizeof (struct grub_partition_bsd_entry))
{
struct grub_partition_bsd_entry be;
p.offset = pos / GRUB_DISK_SECTOR_SIZE;
p.index = pos % GRUB_DISK_SECTOR_SIZE;
if (grub_disk_read (disk, p.offset, p.index, sizeof (be), &be))
return grub_errno;
- p.start = grub_le_to_cpu32 (be.offset) - delta;
+ p.start = grub_le_to_cpu32 (be.offset);
+ if (p.start < delta)
+ continue;
+ p.start -= delta;
p.len = grub_le_to_cpu32 (be.size);
p.partmap = &grub_bsdlabel_partition_map;
+ grub_dprintf ("partition",
+ "partition %d: type 0x%x, start 0x%llx, len 0x%llx\n",
+ p.number, be.fs_type,
+ (unsigned long long) p.start,
+ (unsigned long long) p.len);
+
if (be.fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED)
if (hook (disk, &p))
return grub_errno;
-
- pos += sizeof (struct grub_partition_bsd_entry);
}
return GRUB_ERR_NONE;
}
/* Partition map type. */
static struct grub_partition_map grub_bsdlabel_partition_map =
{
.name = "bsd",