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

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