Reviewed-By : Vladimir Serbinenko<phco...@gmail.com> Le jeu. 27 mars 2025, 20:57, Lidong Chen via Grub-devel <grub-devel@gnu.org> a écrit :
> Fix memory leaks in make_vg() with new helper functions, free_pv() > and free_lv(). Additionally, correct a check after allocating > comp->segments->nodes that mistakenly checked lv->segments->nodes > instead, likely due to a copy-paste error. > > Fixes: CID 473878 > Fixes: CID 473884 > Fixes: CID 473889 > Fixes: CID 473890 > > Signed-off-by: Lidong Chen <lidong.c...@oracle.com> > --- > grub-core/disk/ldm.c | 180 +++++++++++++++++++------------------------ > 1 file changed, 80 insertions(+), 100 deletions(-) > > diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c > index 048e29cd0..0f4f22aaa 100644 > --- a/grub-core/disk/ldm.c > +++ b/grub-core/disk/ldm.c > @@ -179,6 +179,36 @@ gpt_ldm_sector (grub_disk_t dsk) > return sector; > } > > +static void > +free_pv (struct grub_diskfilter_pv *pv) > +{ > + if (pv == NULL) > + return; > + > + grub_free (pv->internal_id); > + grub_free (pv->id.uuid); > + grub_free (pv); > +} > + > +static void > +free_lv (struct grub_diskfilter_lv *lv) > +{ > + if (lv == NULL) > + return; > + > + grub_free (lv->internal_id); > + grub_free (lv->name); > + grub_free (lv->fullname); > + if (lv->segments) > + { > + unsigned int i; > + for (i = 0; i < lv->segment_count; i++) > + grub_free (lv->segments[i].nodes); > + grub_free (lv->segments); > + } > + grub_free (lv); > +} > + > static struct grub_diskfilter_vg * > make_vg (grub_disk_t disk, > const struct grub_ldm_label *label) > @@ -196,12 +226,8 @@ make_vg (grub_disk_t disk, > vg->name = grub_malloc (LDM_NAME_STRLEN + 1); > vg->uuid = grub_malloc (LDM_GUID_STRLEN + 1); > if (! vg->uuid || !vg->name) > - { > - grub_free (vg->uuid); > - grub_free (vg->name); > - grub_free (vg); > - return NULL; > - } > + goto fail1; > + > grub_memcpy (vg->uuid, label->group_guid, LDM_GUID_STRLEN); > grub_memcpy (vg->name, label->group_name, LDM_NAME_STRLEN); > vg->name[LDM_NAME_STRLEN] = 0; > @@ -261,7 +287,7 @@ make_vg (grub_disk_t disk, > pv->internal_id = grub_malloc (sz); > if (!pv->internal_id) > { > - grub_free (pv); > + free_pv (pv); > goto fail2; > } > grub_memcpy (pv->internal_id, ptr, (grub_size_t) ptr[0] + 1); > @@ -271,7 +297,7 @@ make_vg (grub_disk_t disk, > if (ptr + *ptr + 1 >= vblk[i].dynamic > + sizeof (vblk[i].dynamic)) > { > - grub_free (pv); > + free_pv (pv); > goto fail2; > } > /* ptr = name. */ > @@ -279,23 +305,21 @@ make_vg (grub_disk_t disk, > if (ptr + *ptr + 1 > >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) > { > - grub_free (pv); > + free_pv (pv); > goto fail2; > } > pv->id.uuidlen = *ptr; > > if (grub_add (pv->id.uuidlen, 1, &sz)) > { > - grub_free (pv->internal_id); > - grub_free (pv); > + free_pv (pv); > goto fail2; > } > > pv->id.uuid = grub_malloc (sz); > if (pv->id.uuid == NULL) > { > - grub_free (pv->internal_id); > - grub_free (pv); > + free_pv (pv); > goto fail2; > } > grub_memcpy (pv->id.uuid, ptr + 1, pv->id.uuidlen); > @@ -343,7 +367,7 @@ make_vg (grub_disk_t disk, > lv->segments = grub_zalloc (sizeof (*lv->segments)); > if (!lv->segments) > { > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > lv->segments->start_extent = 0; > @@ -354,26 +378,25 @@ make_vg (grub_disk_t disk, > sizeof > (*lv->segments->nodes)); > if (!lv->segments->nodes) > { > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > ptr = vblk[i].dynamic; > if (ptr + *ptr + 1 >= vblk[i].dynamic > + sizeof (vblk[i].dynamic)) > { > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > if (grub_add (ptr[0], 2, &sz)) > { > - grub_free (lv->segments); > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > lv->internal_id = grub_malloc (sz); > if (!lv->internal_id) > { > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > grub_memcpy (lv->internal_id, ptr, ptr[0] + 1); > @@ -383,20 +406,18 @@ make_vg (grub_disk_t disk, > if (ptr + *ptr + 1 >= vblk[i].dynamic > + sizeof (vblk[i].dynamic)) > { > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > if (grub_add (*ptr, 1, &sz)) > { > - grub_free (lv->internal_id); > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > lv->name = grub_malloc (sz); > if (!lv->name) > { > - grub_free (lv->internal_id); > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > grub_memcpy (lv->name, ptr + 1, *ptr); > @@ -405,36 +426,28 @@ make_vg (grub_disk_t disk, > vg->uuid, lv->name); > if (!lv->fullname) > { > - grub_free (lv->internal_id); > - grub_free (lv->name); > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > ptr += *ptr + 1; > if (ptr + *ptr + 1 > >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) > { > - grub_free (lv->internal_id); > - grub_free (lv->name); > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > /* ptr = volume type. */ > ptr += *ptr + 1; > if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) > { > - grub_free (lv->internal_id); > - grub_free (lv->name); > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > /* ptr = flags. */ > ptr += *ptr + 1; > if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) > { > - grub_free (lv->internal_id); > - grub_free (lv->name); > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > > @@ -443,17 +456,13 @@ make_vg (grub_disk_t disk, > /* ptr = number of children. */ > if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) > { > - grub_free (lv->internal_id); > - grub_free (lv->name); > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > ptr += *ptr + 1; > if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) > { > - grub_free (lv->internal_id); > - grub_free (lv->name); > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > > @@ -463,9 +472,7 @@ make_vg (grub_disk_t disk, > || ptr + *ptr + 1>= vblk[i].dynamic > + sizeof (vblk[i].dynamic)) > { > - grub_free (lv->internal_id); > - grub_free (lv->name); > - grub_free (lv); > + free_lv (lv); > goto fail2; > } > lv->size = read_int (ptr + 1, *ptr); > @@ -515,18 +522,18 @@ make_vg (grub_disk_t disk, > ptr = vblk[i].dynamic; > if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) > { > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > if (grub_add (ptr[0], 2, &sz)) > { > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > comp->internal_id = grub_malloc (sz); > if (!comp->internal_id) > { > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > grub_memcpy (comp->internal_id, ptr, ptr[0] + 1); > @@ -535,16 +542,14 @@ make_vg (grub_disk_t disk, > ptr += *ptr + 1; > if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) > { > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > /* ptr = name. */ > ptr += *ptr + 1; > if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) > { > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > /* ptr = state. */ > @@ -554,8 +559,7 @@ make_vg (grub_disk_t disk, > ptr += 4; > if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) > { > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > > @@ -563,16 +567,14 @@ make_vg (grub_disk_t disk, > ptr += *ptr + 1; > if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) > { > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > ptr += 8 + 8; > if (ptr + *ptr + 1 >= vblk[i].dynamic > + sizeof (vblk[i].dynamic)) > { > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > for (lv = vg->lvs; lv; lv = lv->next) > @@ -583,8 +585,7 @@ make_vg (grub_disk_t disk, > } > if (!lv) > { > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > continue; > } > comp->size = lv->size; > @@ -596,8 +597,7 @@ make_vg (grub_disk_t disk, > sizeof (*comp->segments)); > if (!comp->segments) > { > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > } > @@ -608,8 +608,7 @@ make_vg (grub_disk_t disk, > comp->segments = grub_malloc (sizeof (*comp->segments)); > if (!comp->segments) > { > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > comp->segments->start_extent = 0; > @@ -624,27 +623,21 @@ make_vg (grub_disk_t disk, > } > else > { > - grub_free (comp->segments); > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > ptr += *ptr + 1; > ptr++; > if (!(vblk[i].flags & 0x10)) > { > - grub_free (comp->segments); > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic) > || ptr + *ptr + 1 >= vblk[i].dynamic > + sizeof (vblk[i].dynamic)) > { > - grub_free (comp->segments); > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > comp->segments->stripe_size = read_int (ptr + 1, *ptr); > @@ -652,20 +645,16 @@ make_vg (grub_disk_t disk, > if (ptr + *ptr + 1 >= vblk[i].dynamic > + sizeof (vblk[i].dynamic)) > { > - grub_free (comp->segments); > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > comp->segments->node_count = read_int (ptr + 1, *ptr); > comp->segments->node_alloc = comp->segments->node_count; > comp->segments->nodes = grub_calloc > (comp->segments->node_alloc, > sizeof > (*comp->segments->nodes)); > - if (!lv->segments->nodes) > + if (comp->segments->nodes == NULL) > { > - grub_free (comp->segments); > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > } > @@ -677,20 +666,14 @@ make_vg (grub_disk_t disk, > if (grub_mul (lv->segments->node_alloc, 2, > &lv->segments->node_alloc) || > grub_mul (lv->segments->node_alloc, sizeof > (*lv->segments->nodes), &sz)) > { > - grub_free (comp->segments->nodes); > - grub_free (comp->segments); > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > > t = grub_realloc (lv->segments->nodes, sz); > if (!t) > { > - grub_free (comp->segments->nodes); > - grub_free (comp->segments); > - grub_free (comp->internal_id); > - grub_free (comp); > + free_lv (comp); > goto fail2; > } > lv->segments->nodes = t; > @@ -830,7 +813,10 @@ make_vg (grub_disk_t disk, > comp->segments[comp->segment_count].nodes > = grub_malloc (sizeof > (*comp->segments[comp->segment_count].nodes)); > if (!comp->segments[comp->segment_count].nodes) > - goto fail2; > + { > + grub_free (comp->segments); > + goto fail2; > + } > comp->segments[comp->segment_count].nodes[0] = part; > comp->segment_count++; > } > @@ -845,25 +831,19 @@ make_vg (grub_disk_t disk, > struct grub_diskfilter_pv *pv, *next_pv; > for (lv = vg->lvs; lv; lv = next_lv) > { > - unsigned i; > - for (i = 0; i < lv->segment_count; i++) > - grub_free (lv->segments[i].nodes); > - > next_lv = lv->next; > - grub_free (lv->segments); > - grub_free (lv->internal_id); > - grub_free (lv->name); > - grub_free (lv->fullname); > - grub_free (lv); > + free_lv (lv); > + > } > for (pv = vg->pvs; pv; pv = next_pv) > { > next_pv = pv->next; > - grub_free (pv->id.uuid); > - grub_free (pv); > + free_pv (pv); > } > } > + fail1: > grub_free (vg->uuid); > + grub_free (vg->name); > grub_free (vg); > return NULL; > } > -- > 2.34.1 > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel >
_______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel