compare_hash_gnu_hash allocated nentries bytes with alloca. nentries is sh_size / sh_entsize of the symbol table, which comes from the file, so a crafted ELF can make it up to 4GB and overflow the stack.
Allocate it on the heap and explicitly free it on every exit path. Signed-off-by: mohammed mustafa <[email protected]> --- src/elflint.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/elflint.c b/src/elflint.c index dd42dcb4..22b424d6 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -2427,8 +2427,7 @@ hash section [%2zu] '%s' does not contain enough data\n"), } uint32_t nentries = sym_shdr->sh_size / sym_shdr->sh_entsize; - char *used = alloca (nentries); - memset (used, '\0', nentries); + char *used = xcalloc (nentries ?: 1, 1); /* First go over the GNU_HASH table and mark the entries as used. */ const Elf32_Word *gnu_hasharr = (Elf32_Word *) gnu_hash_data->d_buf; @@ -2444,6 +2443,7 @@ hash section [%2zu] '%s' does not contain enough data\n"), ERROR (_("\ hash section [%2zu] '%s' has zero bit mask words\n"), gnu_hash_idx, gnu_hash_name); + free (used); return; } @@ -2455,6 +2455,7 @@ hash section [%2zu] '%s' has zero bit mask words\n"), ERROR (_("\ hash section [%2zu] '%s' uses too much data\n"), gnu_hash_idx, gnu_hash_name); + free (used); return; } @@ -2470,6 +2471,7 @@ hash section [%2zu] '%s' uses too much data\n"), ERROR (_("\ hash section [%2zu] '%s' invalid symbol index %" PRIu32 " (max_nsyms: %" PRIu32 ", nentries: %" PRIu32 "\n"), gnu_hash_idx, gnu_hash_name, symidx, max_nsyms, nentries); + free (used); return; } used[symidx + gnu_symbias] |= 1; @@ -2488,6 +2490,7 @@ hash section [%2zu] '%s' invalid symbol index %" PRIu32 " (max_nsyms: %" PRIu32 ERROR (_("\ hash section [%2zu] '%s' does not contain enough data\n"), hash_idx, hash_name); + free (used); return; } @@ -2499,6 +2502,7 @@ hash section [%2zu] '%s' does not contain enough data\n"), ERROR (_("\ hash section [%2zu] '%s' uses too much data\n"), hash_idx, hash_name); + free (used); return; } @@ -2523,6 +2527,7 @@ hash section [%2zu] '%s' uses too much data\n"), ERROR (_("\ hash section [%2zu] '%s' does not contain enough data\n"), hash_idx, hash_name); + free (used); return; } @@ -2536,6 +2541,7 @@ hash section [%2zu] '%s' does not contain enough data\n"), ERROR (_("\ hash section [%2zu] '%s' uses too much data\n"), hash_idx, hash_name); + free (used); return; } @@ -2557,6 +2563,7 @@ hash section [%2zu] '%s' uses too much data\n"), ERROR (_("\ hash section [%2zu] '%s' invalid sh_entsize\n"), hash_idx, hash_name); + free (used); return; } @@ -2595,6 +2602,8 @@ symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash table elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name)); } } + + free (used); } -- 2.53.0
