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