All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.