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

Reply via email to