Re: [PATCH 1/5] elf-parse: avoid an undefined shift when checking the ELF type

From: Steven Rostedt

Date: Mon Oct 19 2026 - 08:54:12 EST


On Sun, 18 Oct 2026 19:02:14 -0500
Leizhen Zhang <lzsx618@xxxxxxxxx> wrote:

> elf_parse() takes a bitmap of permitted ELF types and tests it with
>
> type = elf_parser.r2(&ehdr->e32.e_type);
> if (!((1 << type) & types)) {
>
> e_type is a 16-bit field read straight out of the file, so a type of 32
> or more shifts by at least the width of int and the result is undefined;
> 31 shifts into the sign bit. All three users of the parser -- kallsyms,
> sorttable and tracepoint-update -- reach this with e_type unvalidated.
>
> Found by fuzzing the host ELF tools with mutated object files under
> ASan/UBSan. Reproducer, on any vmlinux (or any ET_REL object for
> tracepoint-update), setting only e_type:
>
> $ python3 -c 'import struct
> d = bytearray(open("vmlinux","rb").read())
> struct.pack_into("<H", d, 0x10, 40)
> open("t.elf","wb").write(bytes(d))'
>
> $ ./kallsyms --sysmap=/dev/null t.elf
> scripts/elf-parse.c:94:11: runtime error: shift exponent 40 is too
> large for 32-bit type 'int'
> #0 in elf_parse scripts/elf-parse.c:94
>
> (host tools built with -fsanitize=address,undefined)
>
> Reject a type that cannot be in the bitmap, and shift an unsigned 1 so
> that a type of 31 stays defined. No valid object changes behaviour: every
> ET_* value the callers put in the bitmap is far below 32, and a file with
> a larger e_type already took the error path -- it just took it through
> undefined behaviour.
>
> Fixes: b055f4c431e3 ("sorttable: Move ELF parsing into scripts/elf-parse.[ch]")
> Assisted-by: LLM ASan UBSan
> Signed-off-by: Leizhen Zhang <lzsx618@xxxxxxxxx>
> ---
> scripts/elf-parse.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/scripts/elf-parse.c b/scripts/elf-parse.c
> index ce1c2a670244..9e7d1a4f263f 100644
> --- a/scripts/elf-parse.c
> +++ b/scripts/elf-parse.c
> @@ -91,7 +91,8 @@ static int elf_parse(const char *fname, void *addr, uint32_t types)
> }
>
> type = elf_parser.r2(&ehdr->e32.e_type);
> - if (!((1 << type) & types)) {
> + /* e_type comes from the file and the bitmap only has 32 slots. */

This comment is useless, nuke it.

> + if (type >= 32 || !((1U << type) & types)) {
> fprintf(stderr, "Invalid ELF type file %s\n", fname);
> return -1;
> }

Other than that, I'm fine with the patch.

-- Steve