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

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