131 lines
3.1 KiB
Diff
131 lines
3.1 KiB
Diff
From 6a079d978c3c4c77da338b81880799146e47e6bf Mon Sep 17 00:00:00 2001
|
|
From: Daniel Axtens <dja@axtens.net>
|
|
Date: Thu, 21 Jan 2021 18:35:22 +1100
|
|
Subject: [PATCH] disk/lvm: Do not overread metadata
|
|
|
|
We could reach the end of valid metadata and not realize, leading to
|
|
some buffer overreads. Check if we have reached the end and bail.
|
|
|
|
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=1155d7dffd3337942cb7583706b429d567d4db86
|
|
|
|
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
|
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
---
|
|
grub-core/disk/lvm.c | 35 +++++++++++++++++++++++++++++------
|
|
1 file changed, 29 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
|
|
index e5d6c3f..a44861f 100644
|
|
--- a/grub-core/disk/lvm.c
|
|
+++ b/grub-core/disk/lvm.c
|
|
@@ -351,17 +351,23 @@ grub_lvm_detect (grub_disk_t disk,
|
|
while (1)
|
|
{
|
|
grub_ssize_t s;
|
|
- while (grub_isspace (*p))
|
|
+ while (grub_isspace (*p) && p < mda_end)
|
|
p++;
|
|
|
|
+ if (p == mda_end)
|
|
+ goto fail4;
|
|
+
|
|
if (*p == '}')
|
|
break;
|
|
|
|
pv = grub_zalloc (sizeof (*pv));
|
|
q = p;
|
|
- while (*q != ' ')
|
|
+ while (*q != ' ' && q < mda_end)
|
|
q++;
|
|
|
|
+ if (q == mda_end)
|
|
+ goto pvs_fail_noname;
|
|
+
|
|
s = q - p;
|
|
pv->name = grub_malloc (s + 1);
|
|
grub_memcpy (pv->name, p, s);
|
|
@@ -404,6 +410,7 @@ grub_lvm_detect (grub_disk_t disk,
|
|
continue;
|
|
pvs_fail:
|
|
grub_free (pv->name);
|
|
+ pvs_fail_noname:
|
|
grub_free (pv);
|
|
goto fail4;
|
|
}
|
|
@@ -425,18 +432,24 @@ grub_lvm_detect (grub_disk_t disk,
|
|
struct grub_diskfilter_segment *seg;
|
|
int is_pvmove;
|
|
|
|
- while (grub_isspace (*p))
|
|
+ while (grub_isspace (*p) && p < mda_end)
|
|
p++;
|
|
|
|
+ if (p == mda_end)
|
|
+ goto fail4;
|
|
+
|
|
if (*p == '}')
|
|
break;
|
|
|
|
lv = grub_zalloc (sizeof (*lv));
|
|
|
|
q = p;
|
|
- while (*q != ' ')
|
|
+ while (*q != ' ' && q < mda_end)
|
|
q++;
|
|
|
|
+ if (q == mda_end)
|
|
+ goto lvs_fail;
|
|
+
|
|
s = q - p;
|
|
lv->name = grub_strndup (p, s);
|
|
if (!lv->name)
|
|
@@ -608,9 +621,12 @@ grub_lvm_detect (grub_disk_t disk,
|
|
if (p == NULL)
|
|
goto lvs_segment_fail2;
|
|
q = ++p;
|
|
- while (*q != '"')
|
|
+ while (q < mda_end && *q != '"')
|
|
q++;
|
|
|
|
+ if (q == mda_end)
|
|
+ goto lvs_segment_fail2;
|
|
+
|
|
s = q - p;
|
|
|
|
stripe->name = grub_malloc (s + 1);
|
|
@@ -667,9 +683,12 @@ grub_lvm_detect (grub_disk_t disk,
|
|
if (p == NULL)
|
|
goto lvs_segment_fail2;
|
|
q = ++p;
|
|
- while (*q != '"')
|
|
+ while (q < mda_end && *q != '"')
|
|
q++;
|
|
|
|
+ if (q == mda_end)
|
|
+ goto lvs_segment_fail2;
|
|
+
|
|
s = q - p;
|
|
|
|
lvname = grub_malloc (s + 1);
|
|
@@ -825,6 +844,8 @@ grub_lvm_detect (grub_disk_t disk,
|
|
goto cache_lv_fail;
|
|
|
|
p3 = ++p2;
|
|
+ if (p3 == mda_end)
|
|
+ goto cache_lv_fail;
|
|
p3 = grub_strchr (p3, '"');
|
|
if (!p3)
|
|
goto cache_lv_fail;
|
|
@@ -846,6 +867,8 @@ grub_lvm_detect (grub_disk_t disk,
|
|
goto cache_lv_fail;
|
|
|
|
p3 = ++p2;
|
|
+ if (p3 == mda_end)
|
|
+ goto cache_lv_fail;
|
|
p3 = grub_strchr (p3, '"');
|
|
if (!p3)
|
|
goto cache_lv_fail;
|
|
--
|
|
2.19.1
|
|
|