From e27fdbd6866a3dc9c6ee4d777d89c861f04368e7 Mon Sep 17 00:00:00 2001
From: Andrei Borzenkov <arvidjaar@gmail.com>
Date: Sat, 14 Feb 2015 17:55:35 +0300
Subject: [PATCH 283/506] diskfilter: fix crash in validate_lv for mdraid
arrays
Commit 750f4bacd3262376ced3f837d8dc78f834ca233a 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
---
grub-core/disk/diskfilter.c | 23 +++++++----------------
1 file changed, 7 insertions(+), 16 deletions(-)
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
index 80966ac..ad558fa 100644
--- a/grub-core/disk/diskfilter.c
+++ b/grub-core/disk/diskfilter.c
@@ -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)
--
2.4.3