]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
disk/ldm: Make sure comp data is freed before exiting from make_vg()
authorMarco A Benatto <mbenatto@redhat.com>
Mon, 7 Dec 2020 14:53:03 +0000 (11:53 -0300)
committerDaniel Kiper <daniel.kiper@oracle.com>
Tue, 2 Mar 2021 14:54:16 +0000 (15:54 +0100)
Several error handling paths in make_vg() do not free comp data before
jumping to fail2 label and returning from the function. This will leak
memory. So, let's fix all issues of that kind.

Fixes: CID 73804
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
grub-core/disk/ldm.c

index 912e882558a61e07175f5299dbb663f561b3761d..48942549a2e04b4ded1746e8787f6b11450a7bca 100644 (file)
@@ -554,7 +554,11 @@ make_vg (grub_disk_t disk,
              comp->segments = grub_calloc (comp->segment_alloc,
                                            sizeof (*comp->segments));
              if (!comp->segments)
-               goto fail2;
+               {
+                 grub_free (comp->internal_id);
+                 grub_free (comp);
+                 goto fail2;
+               }
            }
          else
            {
@@ -562,7 +566,11 @@ make_vg (grub_disk_t disk,
              comp->segment_count = 1;
              comp->segments = grub_malloc (sizeof (*comp->segments));
              if (!comp->segments)
-               goto fail2;
+               {
+                 grub_free (comp->internal_id);
+                 grub_free (comp);
+                 goto fail2;
+               }
              comp->segments->start_extent = 0;
              comp->segments->extent_count = lv->size;
              comp->segments->layout = 0;
@@ -574,15 +582,26 @@ make_vg (grub_disk_t disk,
                  comp->segments->layout = GRUB_RAID_LAYOUT_SYMMETRIC_MASK;
                }
              else
-               goto fail2;
+               {
+                 grub_free (comp->segments);
+                 grub_free (comp->internal_id);
+                 grub_free (comp);
+                 goto fail2;
+               }
              ptr += *ptr + 1;
              ptr++;
              if (!(vblk[i].flags & 0x10))
-               goto fail2;
+               {
+                 grub_free (comp->segments);
+                 grub_free (comp->internal_id);
+                 grub_free (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);
                  goto fail2;
@@ -592,6 +611,7 @@ 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);
                  goto fail2;
@@ -601,7 +621,12 @@ make_vg (grub_disk_t disk,
              comp->segments->nodes = grub_calloc (comp->segments->node_alloc,
                                                   sizeof (*comp->segments->nodes));
              if (!lv->segments->nodes)
-               goto fail2;
+               {
+                 grub_free (comp->segments);
+                 grub_free (comp->internal_id);
+                 grub_free (comp);
+                 goto fail2;
+               }
            }
 
          if (lv->segments->node_alloc == lv->segments->node_count)
@@ -611,11 +636,23 @@ 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))
-               goto fail2;
+               {
+                 grub_free (comp->segments->nodes);
+                 grub_free (comp->segments);
+                 grub_free (comp->internal_id);
+                 grub_free (comp);
+                 goto fail2;
+               }
 
              t = grub_realloc (lv->segments->nodes, sz);
              if (!t)
-               goto fail2;
+               {
+                 grub_free (comp->segments->nodes);
+                 grub_free (comp->segments);
+                 grub_free (comp->internal_id);
+                 grub_free (comp);
+                 goto fail2;
+               }
              lv->segments->nodes = t;
            }
          lv->segments->nodes[lv->segments->node_count].pv = 0;