1From 1155d7dffd3337942cb7583706b429d567d4db86 Mon Sep 17 00:00:00 2001 2From: Daniel Axtens <dja@axtens.net> 3Date: Thu, 21 Jan 2021 18:35:22 +1100 4Subject: [PATCH] disk/lvm: Do not overread metadata 5 6We could reach the end of valid metadata and not realize, leading to 7some buffer overreads. Check if we have reached the end and bail. 8 9Signed-off-by: Daniel Axtens <dja@axtens.net> 10Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> 11Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com> 12--- 13 grub-core/disk/lvm.c | 31 +++++++++++++++++++++++++------ 14 1 file changed, 25 insertions(+), 6 deletions(-) 15 16diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c 17index bd5ae87..742ecd6 100644 18--- a/grub-core/disk/lvm.c 19+++ b/grub-core/disk/lvm.c 20@@ -313,17 +313,23 @@ grub_lvm_detect (grub_disk_t disk, 21 while (1) 22 { 23 grub_ssize_t s; 24- while (grub_isspace (*p)) 25+ while (grub_isspace (*p) && p < mda_end) 26 p++; 27 28+ if (p == mda_end) 29+ goto fail4; 30+ 31 if (*p == '}') 32 break; 33 34 pv = grub_zalloc (sizeof (*pv)); 35 q = p; 36- while (*q != ' ') 37+ while (*q != ' ' && q < mda_end) 38 q++; 39 40+ if (q == mda_end) 41+ goto pvs_fail_noname; 42+ 43 s = q - p; 44 pv->name = grub_malloc (s + 1); 45 grub_memcpy (pv->name, p, s); 46@@ -366,6 +372,7 @@ grub_lvm_detect (grub_disk_t disk, 47 continue; 48 pvs_fail: 49 grub_free (pv->name); 50+ pvs_fail_noname: 51 grub_free (pv); 52 goto fail4; 53 } 54@@ -387,18 +394,24 @@ grub_lvm_detect (grub_disk_t disk, 55 struct grub_diskfilter_segment *seg; 56 int is_pvmove; 57 58- while (grub_isspace (*p)) 59+ while (grub_isspace (*p) && p < mda_end) 60 p++; 61 62+ if (p == mda_end) 63+ goto fail4; 64+ 65 if (*p == '}') 66 break; 67 68 lv = grub_zalloc (sizeof (*lv)); 69 70 q = p; 71- while (*q != ' ') 72+ while (*q != ' ' && q < mda_end) 73 q++; 74 75+ if (q == mda_end) 76+ goto lvs_fail; 77+ 78 s = q - p; 79 lv->name = grub_strndup (p, s); 80 if (!lv->name) 81@@ -570,9 +583,12 @@ grub_lvm_detect (grub_disk_t disk, 82 if (p == NULL) 83 goto lvs_segment_fail2; 84 q = ++p; 85- while (*q != '"') 86+ while (q < mda_end && *q != '"') 87 q++; 88 89+ if (q == mda_end) 90+ goto lvs_segment_fail2; 91+ 92 s = q - p; 93 94 stripe->name = grub_malloc (s + 1); 95@@ -629,9 +645,12 @@ grub_lvm_detect (grub_disk_t disk, 96 if (p == NULL) 97 goto lvs_segment_fail2; 98 q = ++p; 99- while (*q != '"') 100+ while (q < mda_end && *q != '"') 101 q++; 102 103+ if (q == mda_end) 104+ goto lvs_segment_fail2; 105+ 106 s = q - p; 107 108 lvname = grub_malloc (s + 1); 109-- 1102.14.2 111 112