Blame SOURCES/0420-disk-lvm-Do-not-overread-metadata.patch

b1bcb2
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
b1bcb2
From: Daniel Axtens <dja@axtens.net>
b1bcb2
Date: Thu, 21 Jan 2021 18:35:22 +1100
b1bcb2
Subject: [PATCH] disk/lvm: Do not overread metadata
b1bcb2
b1bcb2
We could reach the end of valid metadata and not realize, leading to
b1bcb2
some buffer overreads. Check if we have reached the end and bail.
b1bcb2
b1bcb2
Signed-off-by: Daniel Axtens <dja@axtens.net>
b1bcb2
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
b1bcb2
---
b1bcb2
 grub-core/disk/lvm.c | 31 +++++++++++++++++++++++++------
b1bcb2
 1 file changed, 25 insertions(+), 6 deletions(-)
b1bcb2
b1bcb2
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
b1bcb2
index 7776a0a0a07..5fb1b69091c 100644
b1bcb2
--- a/grub-core/disk/lvm.c
b1bcb2
+++ b/grub-core/disk/lvm.c
b1bcb2
@@ -314,17 +314,23 @@ error_parsing_metadata:
b1bcb2
 	  while (1)
b1bcb2
 	    {
b1bcb2
 	      grub_ssize_t s;
b1bcb2
-	      while (grub_isspace (*p))
b1bcb2
+	      while (grub_isspace (*p) && p < mda_end)
b1bcb2
 		p++;
b1bcb2
 
b1bcb2
+	      if (p == mda_end)
b1bcb2
+		goto fail4;
b1bcb2
+
b1bcb2
 	      if (*p == '}')
b1bcb2
 		break;
b1bcb2
 
b1bcb2
 	      pv = grub_zalloc (sizeof (*pv));
b1bcb2
 	      q = p;
b1bcb2
-	      while (*q != ' ')
b1bcb2
+	      while (*q != ' ' && q < mda_end)
b1bcb2
 		q++;
b1bcb2
 
b1bcb2
+	      if (q == mda_end)
b1bcb2
+		goto pvs_fail_noname;
b1bcb2
+
b1bcb2
 	      s = q - p;
b1bcb2
 	      pv->name = grub_malloc (s + 1);
b1bcb2
 	      grub_memcpy (pv->name, p, s);
b1bcb2
@@ -367,6 +373,7 @@ error_parsing_metadata:
b1bcb2
 	      continue;
b1bcb2
 	    pvs_fail:
b1bcb2
 	      grub_free (pv->name);
b1bcb2
+	    pvs_fail_noname:
b1bcb2
 	      grub_free (pv);
b1bcb2
 	      goto fail4;
b1bcb2
 	    }
b1bcb2
@@ -388,18 +395,24 @@ error_parsing_metadata:
b1bcb2
 	      struct grub_diskfilter_segment *seg;
b1bcb2
 	      int is_pvmove;
b1bcb2
 
b1bcb2
-	      while (grub_isspace (*p))
b1bcb2
+	      while (grub_isspace (*p) && p < mda_end)
b1bcb2
 		p++;
b1bcb2
 
b1bcb2
+	      if (p == mda_end)
b1bcb2
+		goto fail4;
b1bcb2
+
b1bcb2
 	      if (*p == '}')
b1bcb2
 		break;
b1bcb2
 
b1bcb2
 	      lv = grub_zalloc (sizeof (*lv));
b1bcb2
 
b1bcb2
 	      q = p;
b1bcb2
-	      while (*q != ' ')
b1bcb2
+	      while (*q != ' ' && q < mda_end)
b1bcb2
 		q++;
b1bcb2
 
b1bcb2
+	      if (q == mda_end)
b1bcb2
+		goto lvs_fail;
b1bcb2
+
b1bcb2
 	      s = q - p;
b1bcb2
 	      lv->name = grub_strndup (p, s);
b1bcb2
 	      if (!lv->name)
b1bcb2
@@ -572,9 +585,12 @@ error_parsing_metadata:
b1bcb2
 			  if (p == NULL)
b1bcb2
 			    goto lvs_segment_fail2;
b1bcb2
 			  q = ++p;
b1bcb2
-			  while (*q != '"')
b1bcb2
+			  while (q < mda_end && *q != '"')
b1bcb2
 			    q++;
b1bcb2
 
b1bcb2
+			  if (q == mda_end)
b1bcb2
+			    goto lvs_segment_fail2;
b1bcb2
+
b1bcb2
 			  s = q - p;
b1bcb2
 
b1bcb2
 			  stripe->name = grub_malloc (s + 1);
b1bcb2
@@ -631,9 +647,12 @@ error_parsing_metadata:
b1bcb2
 			  if (p == NULL)
b1bcb2
 			    goto lvs_segment_fail2;
b1bcb2
 			  q = ++p;
b1bcb2
-			  while (*q != '"')
b1bcb2
+			  while (q < mda_end && *q != '"')
b1bcb2
 			    q++;
b1bcb2
 
b1bcb2
+			  if (q == mda_end)
b1bcb2
+			    goto lvs_segment_fail2;
b1bcb2
+
b1bcb2
 			  s = q - p;
b1bcb2
 
b1bcb2
 			  lvname = grub_malloc (s + 1);