bug-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] osdep: linux: getroot: Fix stack exhaustion


From: Andri Yngvason
Subject: [PATCH] osdep: linux: getroot: Fix stack exhaustion
Date: Mon, 18 Mar 2019 14:52:07 +0000

struct mountinfo_entry is c.a. 64k big. It is unwise to put such a large
variable onto the stack as this may cause the stack to grow too large on
systems with smaller stacks.

Signed-off-by: Andri Yngvason <address@hidden>
---
 grub-core/osdep/linux/getroot.c | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c
index 90d92d3ad..4e3ed2019 100644
--- a/grub-core/osdep/linux/getroot.c
+++ b/grub-core/osdep/linux/getroot.c
@@ -385,7 +385,7 @@ grub_find_root_devices_from_mountinfo (const char *dir, 
char **relroot)
   size_t len = 0;
   grub_size_t entry_len, entry_max = 4;
   struct mountinfo_entry *entries;
-  struct mountinfo_entry parent_entry = { 0, 0, 0, "", "", "", "" };
+  static struct mountinfo_entry parent_entry = { 0, 0, 0, "", "", "", "" };
   int i;
   int retry = 0;
   int dir_fd = -1;
@@ -405,27 +405,28 @@ again:
 
   entry_len = 0;
 
+  struct mountinfo_entry* entry = xmalloc (sizeof(*entry));
+
   /* First, build a list of relevant visible mounts.  */
   while (getline (&buf, &len, fp) > 0)
     {
-      struct mountinfo_entry entry;
       int count;
       size_t enc_path_len;
       const char *sep;
 
       if (sscanf (buf, "%d %d %u:%u %s %s%n",
-                 &entry.id, &parent_entry.id, &entry.major, &entry.minor,
-                 entry.enc_root, entry.enc_path, &count) < 6)
+                 &entry->id, &parent_entry.id, &entry->major, &entry->minor,
+                 entry->enc_root, entry->enc_path, &count) < 6)
        continue;
 
-      unescape (entry.enc_root);
-      unescape (entry.enc_path);
+      unescape (entry->enc_root);
+      unescape (entry->enc_path);
 
-      enc_path_len = strlen (entry.enc_path);
+      enc_path_len = strlen (entry->enc_path);
       /* Check that enc_path is a prefix of dir.  The prefix must either be
          the entire string, or end with a slash, or be immediately followed
          by a slash.  */
-      if (strncmp (dir, entry.enc_path, enc_path_len) != 0 ||
+      if (strncmp (dir, entry->enc_path, enc_path_len) != 0 ||
          (enc_path_len && dir[enc_path_len - 1] != '/' &&
           dir[enc_path_len] && dir[enc_path_len] != '/'))
        continue;
@@ -435,10 +436,10 @@ again:
        continue;
 
       sep += sizeof (" - ") - 1;
-      if (sscanf (sep, "%s %s", entry.fstype, entry.device) != 2)
+      if (sscanf (sep, "%s %s", entry->fstype, entry->device) != 2)
        continue;
 
-      unescape (entry.device);
+      unescape (entry->device);
 
       /* Using the mount IDs, find out where this fits in the list of
         visible mount entries we've seen so far.  There are three
@@ -460,7 +461,7 @@ again:
          /* Initialise list.  */
          entry_len = 2;
          entries[0] = parent_entry;
-         entries[1] = entry;
+         entries[1] = *entry;
        }
       else
        {
@@ -470,23 +471,25 @@ again:
                {
                  /* Insert at end, pruning anything previously above this.  */
                  entry_len = i + 2;
-                 entries[i + 1] = entry;
+                 entries[i + 1] = *entry;
                  break;
                }
-             else if (i == 0 && entries[i].id == entry.id)
+             else if (i == 0 && entries[i].id == entry->id)
                {
                  /* Insert at start.  */
                  entry_len++;
                  memmove (entries + 1, entries,
                           (entry_len - 1) * sizeof (*entries));
                  entries[0] = parent_entry;
-                 entries[1] = entry;
+                 entries[1] = *entry;
                  break;
                }
            }
        }
     }
 
+  free(entry);
+
   /* Now scan visible mounts for the ones we're interested in.  */
   for (i = entry_len - 1; i >= 0; i--)
     {
-- 
2.11.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]