From: Daniel Axtens <d...@axtens.net>

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 <d...@axtens.net>
Reviewed-by: Daniel Kiper <daniel.ki...@oracle.com>
---
 grub-core/disk/lvm.c | 35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
index 201097fda..7efbaec79 100644
--- a/grub-core/disk/lvm.c
+++ b/grub-core/disk/lvm.c
@@ -352,17 +352,23 @@ grub_lvm_detect (grub_disk_t disk,
          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);
@@ -405,6 +411,7 @@ grub_lvm_detect (grub_disk_t disk,
              continue;
            pvs_fail:
              grub_free (pv->name);
+           pvs_fail_noname:
              grub_free (pv);
              goto fail4;
            }
@@ -426,18 +433,24 @@ grub_lvm_detect (grub_disk_t disk,
              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)
@@ -609,9 +622,12 @@ grub_lvm_detect (grub_disk_t disk,
                          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);
@@ -668,9 +684,12 @@ grub_lvm_detect (grub_disk_t disk,
                          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);
@@ -826,6 +845,8 @@ grub_lvm_detect (grub_disk_t disk,
                        goto cache_lv_fail;
 
                      p3 = ++p2;
+                     if (p3 == mda_end)
+                       goto cache_lv_fail;
                      p3 = grub_strchr (p3, '"');
                      if (!p3)
                        goto cache_lv_fail;
@@ -847,6 +868,8 @@ grub_lvm_detect (grub_disk_t disk,
                        goto cache_lv_fail;
 
                      p3 = ++p2;
+                     if (p3 == mda_end)
+                       goto cache_lv_fail;
                      p3 = grub_strchr (p3, '"');
                      if (!p3)
                        goto cache_lv_fail;
-- 
2.11.0


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to