From: Daniel Palmer <daniel@thingy.jp>
To: kees@kernel.org, linux-mm@kvack.org
Cc: linux-kernel@vger.kernel.org, Daniel Palmer <daniel@thingy.jp>
Subject: [PATCH] binfmt_elf_fdpic: reject PT_LOAD segments with p_filesz > p_memsz
Date: Fri, 10 Jul 2026 21:14:43 +0900 [thread overview]
Message-ID: <20260710121443.1059549-1-daniel@thingy.jp> (raw)
Both fdpic loaders assume every PT_LOAD segment satisfies
p_filesz <= p_memsz, but this is never validated after the program
headers are read.
A malformed ELF with p_filesz > p_memsz misbehaves in both paths:
- elf_fdpic_map_file_constdisp_on_uclinux() sizes its single
anonymous mapping from p_memsz, then read_code()s p_filesz bytes
into each segment, overrunning the reserved space.
- elf_fdpic_map_file_by_direct_mmap() computes
excess = p_memsz - p_filesz as an unsigned value, which underflows
and drives an oversized anonymous mapping / clear_user().
Validate the invariant once in elf_fdpic_fetch_phdrs(), which is the
common path for both the executable and the interpreter, so every
loader is covered. Do it in a dedicated loop rather than the existing
stack-size loop, which breaks early on PT_GNU_STACK and could skip
later PT_LOAD segments.
Link: https://github.com/fifteenhex/fdpicloaderbug_20260710 # reproducer
Assisted-by: Claude:claude-fable-5 # Discovery of bug, review/rework of patch, reproducer
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
Backstory:
When I got access to fable again I thought I'd let it
recheck all of the nommu related files to see if there were any
horrible bugs.
This is 1 of about 3 bugs that seem legit.
fable did most of the hard work here so I'm not going to claim
to have found this bug. I wrote an initial patch and fable told
me to put the check in a different place to cover another issue
and rewrote the commit message. It knows best. :)
I have checked in my m68k nommu environment that this bug is
valid and allows a bad ELF to corrupt memory using a reproducer
fable helped create. Link is in the commit message. I also checked
this fixes blocks a bad ELF from loading.
fs/binfmt_elf_fdpic.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 7e3108489c83..69aa0e04543b 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -157,6 +157,22 @@ static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params,
if (unlikely(retval != size))
return retval < 0 ? retval : -ENOEXEC;
+ /* reject any PT_LOAD segment that claims to hold more data in the file
+ * than it reserves in memory; the loaders below assume
+ * p_filesz <= p_memsz and overrun/underflow their size arithmetic
+ * otherwise
+ */
+ phdr = params->phdrs;
+ for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
+ if (phdr->p_type != PT_LOAD)
+ continue;
+
+ if (phdr->p_filesz > phdr->p_memsz) {
+ kdebug("Bad segment %d: p_filesz > p_memsz", loop);
+ return -ENOEXEC;
+ }
+ }
+
/* determine stack size for this binary */
phdr = params->phdrs;
for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
--
2.53.0
reply other threads:[~2026-07-10 12:15 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20260710121443.1059549-1-daniel@thingy.jp \
--to=daniel@thingy.jp \
--cc=kees@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.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