Don't scan into non-diskfilter devices having diskfilter names.

* grub-core/disk/diskfilter.c (is_valid_diskfilter_name): New function.
	(scan_disk): New argument accept_diskfilter. Fix recursion depth
	handling.
	(scan_disk_hook): New function.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-05-01 14:59:30 +02:00
parent bdf8886428
commit ee618bd491
2 changed files with 44 additions and 11 deletions

View file

@ -1,3 +1,12 @@
2012-05-01 Vladimir Serbinenko <phcoder@gmail.com>
Don't scan into non-diskfilter devices having diskfilter names.
* grub-core/disk/diskfilter.c (is_valid_diskfilter_name): New function.
(scan_disk): New argument accept_diskfilter. Fix recursion depth
handling.
(scan_disk_hook): New function.
2012-04-29 Bean <bean123ch@gmail.com> 2012-04-29 Bean <bean123ch@gmail.com>
* grub-core/net/drivers/efi/efinet.c (get_card_packet): Fix buffer * grub-core/net/drivers/efi/efinet.c (get_card_packet): Fix buffer

View file

@ -113,7 +113,15 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id,
grub_diskfilter_t diskfilter __attribute__ ((unused))); grub_diskfilter_t diskfilter __attribute__ ((unused)));
static int static int
scan_disk (const char *name) is_valid_diskfilter_name (const char *name)
{
return (grub_memcmp (name, "md", sizeof ("md") - 1) == 0
|| grub_memcmp (name, "lvm/", sizeof ("lvm/") - 1) == 0
|| grub_memcmp (name, "ldm/", sizeof ("ldm/") - 1) == 0);
}
static int
scan_disk (const char *name, int accept_diskfilter)
{ {
auto int hook (grub_disk_t disk, grub_partition_t p); auto int hook (grub_disk_t disk, grub_partition_t p);
int hook (grub_disk_t disk, grub_partition_t p) int hook (grub_disk_t disk, grub_partition_t p)
@ -170,25 +178,41 @@ scan_disk (const char *name)
grub_disk_t disk; grub_disk_t disk;
static int scan_depth = 0; static int scan_depth = 0;
if (!accept_diskfilter && is_valid_diskfilter_name (name))
return 0;
if (scan_depth > 100) if (scan_depth > 100)
return 0; return 0;
scan_depth++;
disk = grub_disk_open (name); disk = grub_disk_open (name);
if (!disk) if (!disk)
{ {
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
scan_depth--;
return 0; return 0;
} }
scan_depth++;
if (hook (disk, 0)) if (hook (disk, 0))
return 1; {
scan_depth--;
return 1;
}
if (grub_partition_iterate (disk, hook)) if (grub_partition_iterate (disk, hook))
return 1; {
scan_depth--; scan_depth--;
return 1;
}
grub_disk_close (disk); grub_disk_close (disk);
scan_depth--;
return 0; return 0;
} }
static int
scan_disk_hook (const char *name)
{
return scan_disk (name, 0);
}
static void static void
scan_devices (const char *arname) scan_devices (const char *arname)
{ {
@ -202,7 +226,7 @@ scan_devices (const char *arname)
if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
&& p->iterate) && p->iterate)
{ {
if ((p->iterate) (scan_disk, pull)) if ((p->iterate) (scan_disk_hook, pull))
return; return;
if (arname && is_lv_readable (find_lv (arname), 1)) if (arname && is_lv_readable (find_lv (arname), 1))
return; return;
@ -214,7 +238,7 @@ scan_devices (const char *arname)
for (lv = vg->lvs; lv; lv = lv->next) for (lv = vg->lvs; lv; lv = lv->next)
if (!lv->scanned && lv->fullname && lv->became_readable_at) if (!lv->scanned && lv->fullname && lv->became_readable_at)
{ {
scan_disk (lv->fullname); scan_disk (lv->fullname, 1);
lv->scanned = 1; lv->scanned = 1;
} }
} }
@ -275,7 +299,7 @@ grub_diskfilter_memberlist (grub_disk_t disk)
if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
&& p->iterate) && p->iterate)
{ {
(p->iterate) (scan_disk, pull); (p->iterate) (scan_disk_hook, pull);
while (pv && pv->disk) while (pv && pv->disk)
pv = pv->next; pv = pv->next;
} }
@ -286,7 +310,7 @@ grub_diskfilter_memberlist (grub_disk_t disk)
for (lv2 = vg->lvs; pv && lv2; lv2 = lv2->next) for (lv2 = vg->lvs; pv && lv2; lv2 = lv2->next)
if (!lv2->scanned && lv2->fullname && lv2->became_readable_at) if (!lv2->scanned && lv2->fullname && lv2->became_readable_at)
{ {
scan_disk (lv2->fullname); scan_disk (lv2->fullname, 1);
lv2->scanned = 1; lv2->scanned = 1;
while (pv && pv->disk) while (pv && pv->disk)
pv = pv->next; pv = pv->next;
@ -1072,7 +1096,7 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id,
lv->became_readable_at = ++inscnt; lv->became_readable_at = ++inscnt;
if (is_lv_readable (lv, 1)) if (is_lv_readable (lv, 1))
{ {
scan_disk (lv->fullname); scan_disk (lv->fullname, 1);
lv->scanned = 1; lv->scanned = 1;
} }
} }
@ -1137,7 +1161,7 @@ grub_diskfilter_get_pv_from_disk (grub_disk_t disk,
struct grub_diskfilter_pv *pv; struct grub_diskfilter_pv *pv;
struct grub_diskfilter_vg *vg; struct grub_diskfilter_vg *vg;
scan_disk (disk->name); scan_disk (disk->name, 1);
for (vg = array_list; vg; vg = vg->next) for (vg = array_list; vg; vg = vg->next)
for (pv = vg->pvs; pv; pv = pv->next) for (pv = vg->pvs; pv; pv = pv->next)
{ {