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 free it through a cleanup attribute, since the function has several early returns. Signed-off-by: mohammed mustafa <[email protected]> --- src/elflint.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/elflint.c b/src/elflint.c index dd42dcb4..f6d9fde8 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -2372,6 +2372,12 @@ section [%2d] '%s': hash table has not even room for initial administrative entr } +static void +free_char_ptr (char **p) +{ + free (*p); +} + /* Compare content of both hash tables, it must be identical. */ static void compare_hash_gnu_hash (Ebl *ebl, GElf_Ehdr *ehdr, size_t hash_idx, @@ -2427,8 +2433,8 @@ 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 __attribute__ ((cleanup (free_char_ptr))) + = 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; -- 2.53.0
