From: Harshit Kumar <[email protected]>
Commit 364419bc ("unstrip: reject symbol tables whose sh_size is below
sh_entsize") was mistakenly pushed from v1 of the patch. Apply the
differences from v2.
* src/unstrip.c: wrap lines exceeding 79 columns.
* tests/run-unstrip-symtab-count.sh: fix test description comments and
copyright attribution. Anchor greps on site-specific prefixes and
use grep -q to suppress stdout.
https://sourceware.org/bugzilla/show_bug.cgi?id=34705
Signed-off-by: Harshit Kumar <[email protected]>
---
src/unstrip.c | 6 +++--
tests/run-unstrip-symtab-count.sh | 45 ++++++++++++++++---------------
2 files changed, 27 insertions(+), 24 deletions(-)
diff --git a/src/unstrip.c b/src/unstrip.c
index 24db7c45..39d5bb65 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -1779,7 +1779,8 @@ more sections in stripped file than debug file --
arguments reversed?"));
Elf_Data *shndxdata = NULL; /* XXX */
- if (shdr_mem.sh_entsize == 0 || shdr_mem.sh_size <
shdr_mem.sh_entsize)
+ if (shdr_mem.sh_entsize == 0
+ || shdr_mem.sh_size < shdr_mem.sh_entsize)
error_exit (0,
_("SYMTAB section cannot have zero sh_entsize"
" or a sh_size smaller than sh_entsize"));
@@ -1848,7 +1849,8 @@ more sections in stripped file than debug file --
arguments reversed?"));
/* Merge the stripped file's symbol table into the unstripped one. */
if (stripped_symtab != NULL
&& (stripped_symtab->shdr.sh_entsize == 0
- || stripped_symtab->shdr.sh_size <
stripped_symtab->shdr.sh_entsize))
+ || (stripped_symtab->shdr.sh_size
+ < stripped_symtab->shdr.sh_entsize)))
error_exit (0,
_("stripped SYMTAB section cannot have zero sh_entsize"
" or a sh_size smaller than sh_entsize"));
diff --git a/tests/run-unstrip-symtab-count.sh
b/tests/run-unstrip-symtab-count.sh
index 6054c5ac..0d1995b4 100755
--- a/tests/run-unstrip-symtab-count.sh
+++ b/tests/run-unstrip-symtab-count.sh
@@ -1,5 +1,5 @@
#! /bin/sh
-# Copyright (C) 2026 Red Hat, Inc.
+# Copyright (C) 2026 Harshit Kumar
# This file is part of elfutils.
#
# This file is free software; you can redistribute it and/or modify
@@ -28,15 +28,15 @@
# of the allocation. It aborted under glibc heap checking before the fix.
#
# symtab1: the stripped file is the malformed one, and its debug file has no
-# symbol table at all. That skips the merge step above and reaches
-# add_new_section_symbols(), where "size_t symndx_map[nsym - 1]" was
-# declared with nsym == 0. Before the fix unstrip accepted this file and
-# produced output; now it is rejected.
+# symbol table at all. The section copy loop rejects the malformed symbol
+# table from the stripped file before it can be propagated.
#
-# symtab2: the stripped file has an empty symbol table while the debug file is
-# valid. Without the guard on stripped_symtab, "stripped_nsym - 1" wrapped
-# to SIZE_MAX, leading to out-of-bounds pointer arithmetic
(&symbols[SIZE_MAX])
-# and a heap-buffer-overflow write in collect_symbols().
+# Case 2 reuses the symtab0 files with the arguments swapped, relying on
+# the argument order to make the malformed file the stripped one and the
+# valid file the debug one. Without the guard on stripped_symtab,
+# "stripped_nsym - 1" wrapped to SIZE_MAX, leading to out-of-bounds pointer
+# arithmetic (&symbols[SIZE_MAX]) and a heap-buffer-overflow write in
+# collect_symbols().
# To regenerate the test files:
#
@@ -65,32 +65,33 @@ debug1=testfile-unstrip-symtab1.debug
testfiles $stripped0 $debug0 $stripped1 $debug1
tempfiles symtab-count.out symtab-count.err
-# Case 0: the debug file has an empty symbol table. This used to corrupt the
-# heap in collect_symbols().
+# Case 0: the unstripped (debug) file has an empty symbol table. This used
+# to corrupt the heap in collect_symbols().
if testrun ${abs_top_builddir}/src/unstrip -o symtab-count.out $stripped0
$debug0 \
2> symtab-count.err
then
- echo >&2 "unstrip accepted a SYMTAB with sh_size smaller than sh_entsize"
+ echo >&2 "unstrip accepted an unstripped SYMTAB with sh_size smaller than
sh_entsize"
exit 1
fi
-grep "sh_size smaller than sh_entsize" symtab-count.err
+grep -q ": unstripped SYMTAB section cannot" symtab-count.err
-# Case 1: the stripped file has sh_entsize one larger than sh_size, and its
-# debug file has no symbol table. This used to build a stack array declared
-# with nsym - 1 == SIZE_MAX elements.
+# Case 1: the stripped file has sh_entsize larger than sh_size, and its
+# debug file has no symbol table. The section copy loop rejects the
+# malformed symbol table.
if testrun ${abs_top_builddir}/src/unstrip -o symtab-count.out $stripped1
$debug1 \
2> symtab-count.err
then
- echo >&2 "unstrip accepted a SYMTAB with sh_size smaller than sh_entsize"
+ echo >&2 "unstrip accepted a stripped SYMTAB with sh_size smaller than
sh_entsize"
exit 1
fi
-grep "sh_size smaller than sh_entsize" symtab-count.err
+grep -q ": SYMTAB section cannot" symtab-count.err
-# Case 2: the stripped file has an empty symbol table while the debug file is
-# valid. This used to corrupt the heap in collect_symbols() by passing an
-# underflowed pointer (&symbols[SIZE_MAX]) when merging symbols.
+# Case 2: symtab0 files with arguments swapped, so the malformed file is
+# the stripped one and the debug file is valid. This used to corrupt the
+# heap in collect_symbols() by passing an underflowed pointer
+# (&symbols[SIZE_MAX]) when merging symbols.
if testrun ${abs_top_builddir}/src/unstrip -o symtab-count.out $debug0
$stripped0 \
2> symtab-count.err
then
@@ -98,7 +99,7 @@ then
exit 1
fi
-grep "sh_size smaller than sh_entsize" symtab-count.err
+grep -q ": stripped SYMTAB section cannot" symtab-count.err
test_cleanup
--
2.56.0