diskfilter: fix double free of lv names for mdraid

Avoid micro-optimization in grub_diskfilter_make_raid and make sure
name and fullname are independent strings. This avoids need to special
case it everywhere else.

Also fix memory leak in failure case in grub_diskfilter_make_raid.

Closes: 41582
This commit is contained in:
Andrei Borzenkov 2015-02-14 19:08:58 +03:00
parent e27fdbd686
commit fc535b32b9

View file

@ -1089,8 +1089,15 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
goto fail; goto fail;
array->lvs->segment_count = 1; array->lvs->segment_count = 1;
array->lvs->visible = 1; array->lvs->visible = 1;
array->lvs->name = array->name; if (array->name)
array->lvs->fullname = array->name; {
array->lvs->name = grub_strdup (array->name);
if (!array->lvs->name)
goto fail;
array->lvs->fullname = grub_strdup (array->name);
if (!array->lvs->fullname)
goto fail;
}
array->lvs->vg = array; array->lvs->vg = array;
array->lvs->idname = grub_malloc (sizeof ("mduuid/") + 2 * uuidlen); array->lvs->idname = grub_malloc (sizeof ("mduuid/") + 2 * uuidlen);
@ -1141,7 +1148,18 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
return array; return array;
fail: fail:
grub_free (array->lvs); if (array->lvs)
{
grub_free (array->lvs->name);
grub_free (array->lvs->fullname);
grub_free (array->lvs->idname);
if (array->lvs->segments)
{
grub_free (array->lvs->segments->nodes);
grub_free (array->lvs->segments);
}
grub_free (array->lvs);
}
while (array->pvs) while (array->pvs)
{ {
pv = array->pvs->next; pv = array->pvs->next;
@ -1250,10 +1268,9 @@ free_array (void)
{ {
unsigned i; unsigned i;
vg->lvs = lv->next; vg->lvs = lv->next;
if (lv->name != lv->fullname) grub_free (lv->fullname);
grub_free (lv->fullname); grub_free (lv->name);
if (lv->name != vg->name) grub_free (lv->idname);
grub_free (lv->name);
for (i = 0; i < lv->segment_count; i++) for (i = 0; i < lv->segment_count; i++)
grub_free (lv->segments[i].nodes); grub_free (lv->segments[i].nodes);
grub_free (lv->segments); grub_free (lv->segments);