Linux kbuild/kconfig development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Leizhen Zhang" <lzsx618@gmail.com>, nathan@kernel.org, nsc@kernel.org
Cc: linux-kbuild@vger.kernel.org, rostedt@goodmis.org, ljs@kernel.org
Subject: Re: [PATCH 2/5] elf-parse: check that the section header table is inside the file
Date: Tue, 20 Oct 2026 00:03:41 +0000	[thread overview]
Message-ID: <sashiko-outbox-178368@kernel.org> (raw)
In-Reply-To: <20261019000218.3977398-3-lzsx618@gmail.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] elf-parse: missing SHN_UNDEF and SHN_XINDEX bounds checks in elf_parse()
--

commit 8e951169d34059326033b08713c8c35ae69b423f
Author: Leizhen Zhang <lzsx618@gmail.com>

elf-parse: check that the section header table is inside the file

This commit passes the mapped file size to elf_parse() to validate that the
ELF header fits in the mapping, the section header table lies within the
mapping bounds, and the section name string table index is in range.

> diff --git a/scripts/elf-parse.c b/scripts/elf-parse.c
> index 9e7d1a4f263fe..0e16a9cf67f45 100644
> --- a/scripts/elf-parse.c
> +++ b/scripts/elf-parse.c

[ ... ]

> @@ -168,6 +176,34 @@ static int elf_parse(const char *fname, void *addr, uint32_t types)
>  			ehdr->e32.e_ident[EI_CLASS], fname);
>  		return -1;
>  	}
> +
> +	/*
> +	 * Everything past here walks the section headers with offsets and
> +	 * indices taken from the file, so the table the ELF header describes
> +	 * has to be inside the mapping first. e_shnum == 0 means the real
> +	 * count lives in section 0, which must then be present to be read.
> +	 */
> +	shoff = ehdr_shoff(ehdr);
> +	shentsize = ehdr_shentsize(ehdr);
> +	shnum = ehdr_shnum(ehdr);
> +	if (shnum == SHN_UNDEF)
> +		shnum = 1;
> +	if (shoff > size || shentsize == 0 ||
> +	    (size - shoff) / shentsize < shnum) {
> +		fprintf(stderr, "ELF section headers out of range: %s\n",
> +			fname);
> +		return -1;
> +	}
> +
> +	/* SHN_XINDEX defers the index to section 0; elf_open_ro() checks it. */
> +	shstrndx = ehdr_shstrndx(ehdr);
> +	if (shstrndx != SHN_XINDEX && ehdr_shnum(ehdr) != SHN_UNDEF &&
> +	    shstrndx >= ehdr_shnum(ehdr)) {
> +		fprintf(stderr, "ELF section name index out of range: %s\n",
> +			fname);
> +		return -1;
> +	}
> +
>  	return 0;
>  }

[Severity: Medium]
Can sorttable and tracepoint-update still read past the end of the mapping
when e_shnum is SHN_UNDEF or e_shstrndx is SHN_XINDEX?

The comment and commit message note that resolving the real section count for
SHN_UNDEF and the section name index for SHN_XINDEX stays with elf_open_ro()
(which is updated in the follow-up commit "elf-parse: check the section
indices that elf_open_ro() takes from the file").

However, sorttable and tracepoint-update do not call elf_open_ro(). Instead,
they call elf_map() and resolve section 0's sh_link and sh_size directly
without bounds checks:

scripts/sorttable.c:do_sort() and
scripts/tracepoint-update.c:process_tracepoints():
	shstrndx = ehdr_shstrndx(ehdr);
	if (shstrndx == SHN_XINDEX)
		shstrndx = shdr_link(shdr_start);
	string_sec = get_index(shdr_start, shentsize, shstrndx);
	secstrings = (const char *)ehdr + shdr_offset(string_sec);

	shnum = ehdr_shnum(ehdr);
	if (shnum == SHN_UNDEF)
		shnum = shdr_size(shdr_start);

If e_shnum == SHN_UNDEF and e_shstrndx is an out-of-range index (not equal to
SHN_XINDEX), elf_parse() skips the shstrndx check because ehdr_shnum(ehdr) ==
SHN_UNDEF, and both tools immediately index shdr_start out of bounds via
get_index(shdr_start, shentsize, shstrndx).

Similarly, if e_shnum == SHN_UNDEF and section 0's sh_size exceeds the number
of section headers that fit in the mapping, or if e_shstrndx == SHN_XINDEX
and section 0's sh_link >= shnum, elf_parse() succeeds and both tools read
past the end of the mapping.

Since elf_parse() already verifies that section 0 lies within the mapping when
shnum > 0, should elf_parse() resolve shdr_size() and shdr_link() from
section 0 and validate the real shnum and shstrndx right here so that all
callers of elf_map() are protected as well?

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261019000218.3977398-1-lzsx618@gmail.com?part=2

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

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-19  0:02 [PATCH 0/5] elf-parse: validate what the host ELF tools read from the file Leizhen Zhang
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-20  0:03   ` sashiko-bot [this message]
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-20  0:03   ` sashiko-bot
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=sashiko-outbox-178368@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=ljs@kernel.org \
    --cc=lzsx618@gmail.com \
    --cc=nathan@kernel.org \
    --cc=nsc@kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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