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 <[email protected]> --- 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 _______________________________________________ Bug-grub mailing list [email protected] https://lists.gnu.org/mailman/listinfo/bug-grub
