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

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