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 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.