mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Leizhen Zhang <lzsx618@gmail.com>
To: nathan@kernel.org, nsc@kernel.org
Cc: linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org,
	rostedt@goodmis.org, ljs@kernel.org,
	Leizhen Zhang <lzsx618@gmail.com>
Subject: [PATCH 0/5] elf-parse: validate what the host ELF tools read from the file
Date: Sun, 18 Oct 2026 19:02:13 -0500	[thread overview]
Message-ID: <20261019000218.3977398-1-lzsx618@gmail.com> (raw)

scripts/elf-parse.c takes the section header table, the section indices and
the symbol table straight out of the file it maps, without checking any of
them against the mapping. All three users -- kallsyms, sorttable and
tracepoint-update -- then index with those values, so a truncated or
corrupted object file makes the tools read outside the mapping, allocate
from a file-supplied count, or divide by zero instead of printing an error.

These are build-time tools fed by the local toolchain, so under
Documentation/process/threat-model.rst this looks like a robustness problem
rather than a vulnerability: reaching it takes a corrupt or hostile object
in the build tree. I am leaving that classification for you to review.

How this was found: the three tools were built with
-fsanitize=address,undefined and driven by a mutational fuzzer that pokes
ELF structure fields (ELF header, section headers, symbol entries) in
otherwise valid objects. Every crash was then reduced to a reproducer that
changes exactly one field of a valid file, which is what each patch quotes.

  1/5  e_type >= 32 shifts by at least the width of int (UB). Hits all three
       tools, and is in mainline as well as -next.
  2/5  nothing checks that the file is long enough for its ELF header, or
       that e_shoff/e_shnum/e_shstrndx describe a table inside the mapping.
       Also mainline.
  3/5  elf_open_ro() resolves a count and a name index through section 0 and
       a string table through sh_link, all unchecked. -next only.
  4/5  a zero sh_entsize divides by zero, and an sh_size past the end of the
       file yields an unbounded symbol count which the caller allocates.
       -next only.
  5/5  st_name is unbounded, so one symbol can point its name anywhere.
       -next only.

Verification, per patch, on the reproducer it quotes and on a valid vmlinux,
a shared object and a .o: every reproducer now prints one line and exits 1,
and the three tools accept the valid objects unchanged. After the series the
fuzzer no longer reaches any of these paths (3420 kallsyms, 2149 sorttable
and 2594 tracepoint-update iterations). gcc -Wall -Wextra is clean on the
changed files, and checkpatch --strict reports nothing except CamelCase
complaints about the standard ELF type names.

What is NOT fixed, and what I could not do:

 - An unaligned symbol-table sh_offset makes elf_symbol() form a misaligned
   Elf_Sym pointer, which UBSan reports at scripts/elf-parse.h:233. Checking
   alignment here would reject legitimate ELF32 objects, whose symbol tables
   need 4-byte alignment while the Elf_Sym union wants 8, so this wants the
   accessors to read unaligned instead. Patch 4/5 says so in its message.
 - Reading e_shoff itself through get_unaligned_le32() is UB on a byte with
   the top bit set. That is a separate bug in
   tools/include/tools/le_byteshift.h which I have a patch pending for
   ("tools/include: fix signed shift overflow in 32-bit unaligned
   accessors"). Until it lands, the e_shoff reproducer in 2/5 stops at the
   byteshift report first; with it applied the behaviour is as described.
 - sorttable.c and tracepoint-update.c read *section* names the same
   unbounded way through the elf_map() path. Both crash, both have a
   one-field reproducer, and both are sent as separate patches to their own
   maintainers rather than buried in this series.
 - The series is based on next-20261002, the newest linux-next I could fetch
   here. Patches 1 and 2 apply to mainline as well.
 - Per Documentation/process/coding-assistants.rst each patch carries an
   Assisted-by tag recording that an LLM found and drafted it, along with
   the sanitizers used. The Signed-off-by is mine: I reviewed the analysis
   and the code.

Leizhen Zhang (5):
  elf-parse: avoid an undefined shift when checking the ELF type
  elf-parse: check that the section header table is inside the file
  elf-parse: check the section indices that elf_open_ro() takes from the
    file
  elf-parse: check the symbol table before walking it
  elf-parse: bound symbol names by the string table

 scripts/elf-parse.c       | 125 +++++++++++++++++++++++++++++++++++---
 scripts/elf-parse.h       |  14 +++++
 scripts/kallsyms-sysmap.c |   4 +-
 3 files changed, 133 insertions(+), 10 deletions(-)

-- 
2.34.1


             reply	other threads:[~2026-10-19  0:03 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-19  0:02 Leizhen Zhang [this message]
2026-10-19  0:02 ` [PATCH 1/5] elf-parse: avoid an undefined shift when checking the ELF type Leizhen Zhang
2026-10-19 12:47   ` Steven Rostedt
2026-10-19  0:02 ` [PATCH 2/5] elf-parse: check that the section header table is inside the file Leizhen Zhang
2026-10-19 12:55   ` Steven Rostedt
2026-10-19  0:02 ` [PATCH 3/5] elf-parse: check the section indices that elf_open_ro() takes from " Leizhen Zhang
2026-10-19  0:02 ` [PATCH 4/5] elf-parse: check the symbol table before walking it Leizhen Zhang
2026-10-19  0:02 ` [PATCH 5/5] elf-parse: bound symbol names by the string table Leizhen Zhang
2026-10-19 12:57 ` [PATCH 0/5] elf-parse: validate what the host ELF tools read from the file Steven Rostedt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261019000218.3977398-1-lzsx618@gmail.com \
    --to=lzsx618@gmail.com \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ljs@kernel.org \
    --cc=nathan@kernel.org \
    --cc=nsc@kernel.org \
    --cc=rostedt@goodmis.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®