]> git.proxmox.com Git - grub2.git/commitdiff
disk/lvm: Do not overread metadata
authorDaniel Axtens <dja@axtens.net>
Thu, 21 Jan 2021 07:35:22 +0000 (18:35 +1100)
committerColin Watson <cjwatson@debian.org>
Sun, 13 Jun 2021 23:40:46 +0000 (00:40 +0100)
We could reach the end of valid metadata and not realize, leading to
some buffer overreads. Check if we have reached the end and bail.

Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Patch-Name: 2021-02-security/088-disk-lvm-Do-not-overread-metadata.patch

grub-core/disk/lvm.c

index 60024feafa1f717e2b731088262301d6900f0f41..8b099aeafe4df3c574c05683a06f0ea50e0926ea 100644 (file)
@@ -313,17 +313,23 @@ error_parsing_metadata:
          while (1)
            {
              grub_ssize_t s;
-             while (grub_isspace (*p))
+             while (grub_isspace (*p) && p < mda_end)
                p++;
 
+             if (p == mda_end)
+               goto fail4;
+
              if (*p == '}')
                break;
 
              pv = grub_zalloc (sizeof (*pv));
              q = p;
-             while (*q != ' ')
+             while (*q != ' ' && q < mda_end)
                q++;
 
+             if (q == mda_end)
+               goto pvs_fail_noname;
+
              s = q - p;
              pv->name = grub_malloc (s + 1);
              grub_memcpy (pv->name, p, s);
@@ -366,6 +372,7 @@ error_parsing_metadata:
              continue;
            pvs_fail:
              grub_free (pv->name);
+           pvs_fail_noname:
              grub_free (pv);
              goto fail4;
            }
@@ -387,18 +394,24 @@ error_parsing_metadata:
              struct grub_diskfilter_segment *seg;
              int is_pvmove;
 
-             while (grub_isspace (*p))
+             while (grub_isspace (*p) && p < mda_end)
                p++;
 
+             if (p == mda_end)
+               goto fail4;
+
              if (*p == '}')
                break;
 
              lv = grub_zalloc (sizeof (*lv));
 
              q = p;
-             while (*q != ' ')
+             while (*q != ' ' && q < mda_end)
                q++;
 
+             if (q == mda_end)
+               goto lvs_fail;
+
              s = q - p;
              lv->name = grub_strndup (p, s);
              if (!lv->name)
@@ -569,9 +582,12 @@ error_parsing_metadata:
                          if (p == NULL)
                            goto lvs_segment_fail2;
                          q = ++p;
-                         while (*q != '"')
+                         while (q < mda_end && *q != '"')
                            q++;
 
+                         if (q == mda_end)
+                           goto lvs_segment_fail2;
+
                          s = q - p;
 
                          stripe->name = grub_malloc (s + 1);
@@ -628,9 +644,12 @@ error_parsing_metadata:
                          if (p == NULL)
                            goto lvs_segment_fail2;
                          q = ++p;
-                         while (*q != '"')
+                         while (q < mda_end && *q != '"')
                            q++;
 
+                         if (q == mda_end)
+                           goto lvs_segment_fail2;
+
                          s = q - p;
 
                          lvname = grub_malloc (s + 1);