From: Jori Koolstra <jkoolstra@xs4all.nl>
To: Vivek Parikh <viv0411.parikh@gmail.com>
Cc: viro@zeniv.linux.org.uk, brauner@kernel.org, kees@kernel.org,
linux-fsdevel@vger.kernel.org
Subject: Re: [REPORT] binfmt_misc: leaked write-access denial on F-flag interpreter inode
Date: Sun, 19 Jul 2026 13:47:10 +0200 [thread overview]
Message-ID: <aly4-PR3FQQb-zAd@daedalus> (raw)
In-Reply-To: <CAHKnOm098q+3rjU9Ybo9vJYOW1K0h+A1hPFt8nw+6bEmcwywSA@mail.gmail.com>
On Sat, Jul 18, 2026 at 10:13:46AM +0530, Vivek Parikh wrote:
> Note: this bug was found with AI assistance, so I am treating it as public
> per Documentation/process/security-bugs. A reproducer (unprivileged C PoC)
> is available on request; I am not posting it here.
>
> Summary
> -------
> put_binfmt_handler() closes an F-flag (MISC_FMT_OPEN_FILE) entry's
> interpreter file without restoring the write access that open_exec()
> denied at registration. Every register/delete cycle of an F entry leaks
> one i_writecount denial on the interpreter's inode, so that inode returns
> -ETXTBSY to all writers until it is evicted from the inode cache or the
> machine reboots.
>
> Affected versions
> -----------------
> Introduced in v4.7 by commit 948b701a607f. Present through v7.2.0-rc3
> (fs/binfmt_misc.c:162-168). Root-only from v4.7; reachable by an
> unprivileged user from v6.7 onward, when binfmt_misc gained
> FS_USERNS_MOUNT and can be mounted inside a user namespace with no
> capability check on registration (on systems that permit unprivileged
> user namespaces).
>
> Details
> -------
> Registration of an F entry opens the interpreter via open_exec()
> (fs/binfmt_misc.c:821), which calls exe_file_deny_write_access() in
> do_open_execat() (fs/exec.c:800). do_open_execat() documents that the
> caller must call exe_file_allow_write_access() before releasing the file.
>
> The registration error path honors this (fs/binfmt_misc.c:834):
>
> exe_file_allow_write_access(f);
> filp_close(f, NULL);
>
> The teardown path does not (fs/binfmt_misc.c:162-168):
>
> static void put_binfmt_handler(Node *e)
> {
> if (refcount_dec_and_test(&e->users)) {
> if (e->flags & MISC_FMT_OPEN_FILE)
> filp_close(e->interp_file, NULL);
> kfree(e);
> }
> }
>
> filp_close()/fput() do not reverse the deny count, so the denial is
> leaked. This is the persistent file opened by open_exec() at
> registration; it is distinct from the per-exec clone made in
> load_misc_binary() (fs/binfmt_misc.c:251-254), which is released
> elsewhere.
>
> Reproduction (conditions)
> -------------------------
> - CONFIG_BINFMT_MISC enabled.
> - For the unprivileged case: kernel/distro permitting unprivileged user
> namespaces (v6.7+ for the userns-mount path).
> - Steps: mount binfmt_misc; register ":x:E::x::<victim>:F" for any
> world-readable regular file on a non-noexec mount; delete the entry
> ("echo -1"); open(victim, O_WRONLY) then fails with -ETXTBSY.
> The victim needs no execute bit; open_exec only requires a regular file
> on a non-noexec mount.
>
> Verified: unprivileged (uid 1000) on a 7.0.0-27-generic host, and as
> root on a 7.2.0-rc3 build.
>
> Fix
> ---
> Mirror the registration error-path fix on the teardown path.
> exe_file_allow_write_access() is NULL-safe and skips the same
> FMODE_FSNOTIFY_HSM files that exe_file_deny_write_access() skipped, so
> no imbalance is possible.
>
> diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
> --- a/fs/binfmt_misc.c
> +++ b/fs/binfmt_misc.c
> @@ -162,8 +162,10 @@ static void put_binfmt_handler(Node *e)
> static void put_binfmt_handler(Node *e)
> {
> if (refcount_dec_and_test(&e->users)) {
> - if (e->flags & MISC_FMT_OPEN_FILE)
> + if (e->flags & MISC_FMT_OPEN_FILE) {
> + exe_file_allow_write_access(e->interp_file);
> filp_close(e->interp_file, NULL);
> + }
> kfree(e);
> }
> }
>
> Fixes: 948b701a607f ("binfmt_misc: add persistent opened binary
> handler for containers")
> Signed-off-by: Vivek Parikh <viv0411.parikh@gmail.com>
Thanks!
This is already addressed by a recent patchset of Brauner.[1]
Best,
Jori.
[1]: https://lore.kernel.org/linux-fsdevel/20260710-work-binfmt_misc-locking-v3-1-a162f7cb58d6@kernel.org/
prev parent reply other threads:[~2026-07-19 11:46 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-18 4:43 [REPORT] binfmt_misc: leaked write-access denial on F-flag interpreter inode Vivek Parikh
2026-07-19 11:47 ` Jori Koolstra [this message]
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=aly4-PR3FQQb-zAd@daedalus \
--to=jkoolstra@xs4all.nl \
--cc=brauner@kernel.org \
--cc=kees@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
--cc=viv0411.parikh@gmail.com \
/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