diskfilter: fix crash in validate_lv for mdraid arrays

Commit 750f4bacd3 put LV validation before
actual vg assignment. Make grub_diskfilter_make_raid to assign ->vg as
happens in other cases for consistency. Also clean up redundant code and add
explicit NULL lv->vg check in validate_lv.

Also fix segment validation in validate_lv; it became obvious when crash
was fixed.

Closes: 44199
This commit is contained in:
Andrei Borzenkov 2015-02-14 17:55:35 +03:00
parent 32cd33bd19
commit e27fdbd686

View file

@ -496,13 +496,13 @@ validate_lv (struct grub_diskfilter_lv *lv)
if (!lv)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown volume");
if (lv->vg->extent_size == 0)
if (!lv->vg || lv->vg->extent_size == 0)
return grub_error (GRUB_ERR_READ_ERROR, "invalid volume");
for (i = 0; i < lv->segment_count; i++)
{
grub_err_t err;
err = validate_segment (&lv->segments[1]);
err = validate_segment (&lv->segments[i]);
if (err)
return err;
}
@ -941,8 +941,10 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg)
for (lv = vg->lvs; lv; lv = lv->next)
{
/* RAID 1 and single-disk RAID 0 don't use a chunksize but code assumes one so set
one. */
grub_err_t err;
/* RAID 1 and single-disk RAID 0 don't use a chunksize but code
assumes one so set one. */
for (i = 0; i < lv->segment_count; i++)
{
if (lv->segments[i].type == 1)
@ -952,17 +954,6 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg)
&& lv->segments[i].stripe_size == 0)
lv->segments[i].stripe_size = 64;
}
}
for (lv = vg->lvs; lv; lv = lv->next)
{
grub_err_t err;
/* RAID 1 doesn't use a chunksize but code assumes one so set
one. */
for (i = 0; i < lv->segment_count; i++)
if (lv->segments[i].type == 1)
lv->segments[i].stripe_size = 64;
err = validate_lv(lv);
if (err)
@ -1007,7 +998,6 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg)
lv->fullname = tmp;
}
}
lv->vg = vg;
}
/* Add our new array to the list. */
vg->next = array_list;
@ -1101,6 +1091,7 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
array->lvs->visible = 1;
array->lvs->name = array->name;
array->lvs->fullname = array->name;
array->lvs->vg = array;
array->lvs->idname = grub_malloc (sizeof ("mduuid/") + 2 * uuidlen);
if (!array->lvs->idname)