hc
2024-07-16 5fbd6e2385615a225453562361c4bdab3b15fda1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
From 23e39f50ca7a107f6b66396ed4d177a914dee035 Mon Sep 17 00:00:00 2001
From: Marco A Benatto <mbenatto@redhat.com>
Date: Mon, 7 Dec 2020 11:53:03 -0300
Subject: [PATCH] disk/ldm: Make sure comp data is freed before exiting from
 make_vg()
 
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>
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
---
 grub-core/disk/ldm.c | 51 ++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 44 insertions(+), 7 deletions(-)
 
diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
index 58f8a53..428415f 100644
--- a/grub-core/disk/ldm.c
+++ b/grub-core/disk/ldm.c
@@ -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;
-- 
2.14.2