* [PATCH] scripts/sorttable: fix off-by-one in do_sort() symbol-table walk
@ 2026-04-27 22:03 Hasan Basbunar
0 siblings, 0 replies; only message in thread
From: Hasan Basbunar @ 2026-04-27 22:03 UTC (permalink / raw)
To: linux-kernel; +Cc: Steven Rostedt, Hasan Basbunar
The for-loop in do_sort() that searches .symtab for the
main_extable_sort_needed flag uses a strict less-than predicate that
includes the symentsize:
for (sym = sym_start; (void *)sym + symentsize < sym_end;
sym = (void *)sym + symentsize) {
For a .symtab of N entries each symentsize bytes,
sym_end - sym_start == N * symentsize. After k advances sym is at offset
k * symentsize, so the predicate (void *)sym + symentsize < sym_end
reduces to (k+1) * symentsize < N * symentsize, i.e. k < N-1. The body
therefore runs for k = 0..N-2 only — N-1 iterations — and the entry at
index N-1 is never visited. If main_extable_sort_needed happens to
occupy the very last slot of .symtab, the search silently fails,
sort_needed_sym stays NULL, and do_sort() prints
no main_extable_sort_needed symbol in file: <vmlinux>
aborting the post-link sort and failing the kernel build for any link
order that places that symbol last.
The companion loop just above in the same file at scripts/sorttable.c:563
(get_mcount_loc()) walks the same .symtab correctly:
while (sym < end_sym) {
...
sym = (void *)sym + symentsize;
}
and includes the final entry. The two loops disagreed on whether the
last symbol is part of the table — clearly unintended.
Align do_sort()'s walk on the companion loop's predicate so every
.symtab entry is examined. sym_end is the one-past-the-end pointer of
the .symtab mapping (sym_start + shdr_size(symtab_sec)), so a single
(void *)sym < sym_end check is sufficient and matches the
get_mcount_loc() pattern verbatim.
Reproduced with a stand-alone harness lifting the predicate verbatim:
on a 5-entry synthetic .symtab the buggy form visits 4 entries and
misses the last; the fixed form visits all 5.
Fixes: 200d015e73b4 ("scripts/sorttable: Convert Elf_Sym MACRO over to a union")
Signed-off-by: Hasan Basbunar <basbunarhasan@gmail.com>
---
scripts/sorttable.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
index e8ed11c680c6..dd69b1a9f9ec 100644
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -751,7 +751,7 @@ static int do_sort(Elf_Ehdr *ehdr,
sym_end = sym_start + shdr_size(symtab_sec);
symentsize = shdr_entsize(symtab_sec);
- for (sym = sym_start; (void *)sym + symentsize < sym_end;
+ for (sym = sym_start; (void *)sym < sym_end;
sym = (void *)sym + symentsize) {
if (sym_type(sym) != STT_OBJECT)
continue;
--
2.53.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-04-27 22:04 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-27 22:03 [PATCH] scripts/sorttable: fix off-by-one in do_sort() symbol-table walk Hasan Basbunar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox