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