* FAILED: patch "[PATCH] binfmt_misc: restore write access when removing an entry" failed to apply to 6.1-stable tree
@ 2026-08-05 9:54 gregkh
2026-08-12 9:11 ` [PATCH 6.1.y 1/3] fsnotify: opt-in for permission events at file open time Sasha Levin
0 siblings, 1 reply; 4+ messages in thread
From: gregkh @ 2026-08-05 9:54 UTC (permalink / raw)
To: brauner; +Cc: stable
The patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x db1856ea9196cf6e015d12199a34c0b9313c7bfa
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026080512-populace-barterer-83d7@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From db1856ea9196cf6e015d12199a34c0b9313c7bfa Mon Sep 17 00:00:00 2001
From: Christian Brauner <brauner@kernel.org>
Date: Fri, 10 Jul 2026 11:33:02 +0200
Subject: [PATCH] binfmt_misc: restore write access when removing an entry
Registering an entry with the MISC_FMT_OPEN_FILE flag opens the
interpreter via open_exec() which denies write access to it for as
long as the entry exists. Removing the entry closes the interpreter
file via filp_close() but never restores write access, leaving the
inode's i_writecount permanently negative. Opening the interpreter
for writing keeps failing with ETXTBSY long after the entry is gone
until the inode is evicted from the inode cache.
Commit 90f601b497d7 ("binfmt_misc: restore write access before
closing files opened by open_exec()") fixed the same imbalance in the
error path of bm_register_write() but the actual removal path has
been leaking the write denial since the introduction of the flag.
Restore write access in put_binfmt_handler() before closing the
interpreter file.
Link: https://patch.msgid.link/20260710-work-binfmt_misc-locking-v3-1-a162f7cb58d6@kernel.org
Fixes: 948b701a607f ("binfmt_misc: add persistent opened binary handler for containers")
Cc: stable@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 47aeb2b68d3e..adab06d18550 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -162,8 +162,10 @@ static Node *get_binfmt_handler(struct binfmt_misc *misc,
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);
}
}
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 6.1.y 1/3] fsnotify: opt-in for permission events at file open time
2026-08-05 9:54 FAILED: patch "[PATCH] binfmt_misc: restore write access when removing an entry" failed to apply to 6.1-stable tree gregkh
@ 2026-08-12 9:11 ` Sasha Levin
2026-08-12 9:11 ` [PATCH 6.1.y 2/3] fs: don't block write during exec on pre-content watched files Sasha Levin
2026-08-12 9:11 ` [PATCH 6.1.y 3/3] binfmt_misc: restore write access when removing an entry Sasha Levin
0 siblings, 2 replies; 4+ messages in thread
From: Sasha Levin @ 2026-08-12 9:11 UTC (permalink / raw)
To: stable; +Cc: Amir Goldstein, Linus Torvalds, Jan Kara, Sasha Levin
From: Amir Goldstein <amir73il@gmail.com>
[ Upstream commit a94204f4d48e28a711b7ed10399f749286c433e3 ]
Legacy inotify/fanotify listeners can add watches for events on inode,
parent or mount and expect to get events (e.g. FS_MODIFY) on files that
were already open at the time of setting up the watches.
fanotify permission events are typically used by Anti-malware sofware,
that is watching the entire mount and it is not common to have more that
one Anti-malware engine installed on a system.
To reduce the overhead of the fsnotify_file_perm() hooks on every file
access, relax the semantics of the legacy FAN_ACCESS_PERM event to generate
events only if there were *any* permission event listeners on the
filesystem at the time that the file was opened.
The new semantic is implemented by extending the FMODE_NONOTIFY bit into
two FMODE_NONOTIFY_* bits, that are used to store a mode for which of the
events types to report.
This is going to apply to the new fanotify pre-content events in order
to reduce the cost of the new pre-content event vfs hooks.
[Thanks to Bert Karwatzki <spasswolf@web.de> for reporting a bug in this
code with CONFIG_FANOTIFY_ACCESS_PERMISSIONS disabled]
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/linux-fsdevel/CAHk-=wj8L=mtcRTi=NECHMGfZQgXOp_uix1YVh04fEmrKaMnXA@mail.gmail.com/
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/5ea5f8e283d1edb55aa79c35187bfe344056af14.1731684329.git.josef@toxicpanda.com
Stable-dep-of: db1856ea9196 ("binfmt_misc: restore write access when removing an entry")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/fs.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 02c83cd07d4f2..c1bd804b86153 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -184,6 +184,12 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
/* File supports async nowait buffered writes */
#define FMODE_BUF_WASYNC ((__force fmode_t)0x80000000)
+/*
+ * fsnotify pre-content events do not exist in this kernel, so a file is never
+ * watched by a pre-content event listener.
+ */
+#define FMODE_FSNOTIFY_HSM(mode) 0
+
/*
* Attribute flags. These should be or-ed together to figure out what
* has been changed!
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 6.1.y 2/3] fs: don't block write during exec on pre-content watched files
2026-08-12 9:11 ` [PATCH 6.1.y 1/3] fsnotify: opt-in for permission events at file open time Sasha Levin
@ 2026-08-12 9:11 ` Sasha Levin
2026-08-12 9:11 ` [PATCH 6.1.y 3/3] binfmt_misc: restore write access when removing an entry Sasha Levin
1 sibling, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-08-12 9:11 UTC (permalink / raw)
To: stable; +Cc: Amir Goldstein, Christian Brauner, Jan Kara, Sasha Levin
From: Amir Goldstein <amir73il@gmail.com>
[ Upstream commit 0357ef03c94ef835bd44a0658b8edb672a9dbf51 ]
Commit 2a010c412853 ("fs: don't block i_writecount during exec") removed
the legacy behavior of getting ETXTBSY on attempt to open and executable
file for write while it is being executed.
This commit was reverted because an application that depends on this
legacy behavior was broken by the change.
We need to allow HSM writing into executable files while executed to
fill their content on-the-fly.
To that end, disable the ETXTBSY legacy behavior for files that are
watched by pre-content events.
This change is not expected to cause regressions with existing systems
which do not have any pre-content event listeners.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Acked-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20241128142532.465176-1-amir73il@gmail.com
Stable-dep-of: db1856ea9196 ("binfmt_misc: restore write access when removing an entry")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/binfmt_elf.c | 4 ++--
fs/binfmt_elf_fdpic.c | 4 ++--
fs/exec.c | 6 +++---
include/linux/fs.h | 22 ++++++++++++++++++++++
kernel/fork.c | 12 ++++++------
5 files changed, 35 insertions(+), 13 deletions(-)
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 2fa739f2f7bb8..300d372057837 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1288,7 +1288,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
}
reloc_func_desc = interp_load_addr;
- allow_write_access(interpreter);
+ exe_file_allow_write_access(interpreter);
fput(interpreter);
kfree(interp_elf_ex);
@@ -1397,7 +1397,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
kfree(interp_elf_ex);
kfree(interp_elf_phdata);
out_free_file:
- allow_write_access(interpreter);
+ exe_file_allow_write_access(interpreter);
if (interpreter)
fput(interpreter);
out_free_ph:
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index b2d3b6e43bb56..c5528cad47d44 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -394,7 +394,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
goto error;
}
- allow_write_access(interpreter);
+ exe_file_allow_write_access(interpreter);
fput(interpreter);
interpreter = NULL;
}
@@ -467,7 +467,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
error:
if (interpreter) {
- allow_write_access(interpreter);
+ exe_file_allow_write_access(interpreter);
fput(interpreter);
}
kfree(interpreter_name);
diff --git a/fs/exec.c b/fs/exec.c
index a4d21a67723d7..5ad7121f0cd4e 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -937,7 +937,7 @@ static struct file *do_open_execat(int fd, struct filename *name, int flags)
path_noexec(&file->f_path))
goto exit;
- err = deny_write_access(file);
+ err = exe_file_deny_write_access(file);
if (err)
goto exit;
@@ -1520,7 +1520,7 @@ static void free_bprm(struct linux_binprm *bprm)
abort_creds(bprm->cred);
}
if (bprm->file) {
- allow_write_access(bprm->file);
+ exe_file_allow_write_access(bprm->file);
fput(bprm->file);
}
if (bprm->executable)
@@ -1812,7 +1812,7 @@ static int exec_binprm(struct linux_binprm *bprm)
bprm->file = bprm->interpreter;
bprm->interpreter = NULL;
- allow_write_access(exec);
+ exe_file_allow_write_access(exec);
if (unlikely(bprm->have_execfd)) {
if (bprm->executable) {
fput(exec);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index c1bd804b86153..d4b0e4630e08e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3110,6 +3110,28 @@ static inline void allow_write_access(struct file *file)
if (file)
atomic_inc(&file_inode(file)->i_writecount);
}
+
+/*
+ * Do not prevent write to executable file when watched by pre-content events.
+ *
+ * Note that FMODE_FSNOTIFY_HSM mode is set depending on pre-content watches at
+ * the time of file open and remains constant for entire lifetime of the file,
+ * so if pre-content watches are added post execution or removed before the end
+ * of the execution, it will not cause i_writecount reference leak.
+ */
+static inline int exe_file_deny_write_access(struct file *exe_file)
+{
+ if (unlikely(FMODE_FSNOTIFY_HSM(exe_file->f_mode)))
+ return 0;
+ return deny_write_access(exe_file);
+}
+static inline void exe_file_allow_write_access(struct file *exe_file)
+{
+ if (unlikely(!exe_file || FMODE_FSNOTIFY_HSM(exe_file->f_mode)))
+ return;
+ allow_write_access(exe_file);
+}
+
static inline bool inode_is_open_for_write(const struct inode *inode)
{
return atomic_read(&inode->i_writecount) > 0;
diff --git a/kernel/fork.c b/kernel/fork.c
index 63f56a292f756..ce2aae5734fee 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -576,8 +576,8 @@ static void dup_mm_exe_file(struct mm_struct *mm, struct mm_struct *oldmm)
* We depend on the oldmm having properly denied write access to the
* exe_file already.
*/
- if (exe_file && deny_write_access(exe_file))
- pr_warn_once("deny_write_access() failed in %s\n", __func__);
+ if (exe_file && exe_file_deny_write_access(exe_file))
+ pr_warn_once("exe_file_deny_write_access() failed in %s\n", __func__);
}
#ifdef CONFIG_MMU
@@ -1275,13 +1275,13 @@ int set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
* We expect the caller (i.e., sys_execve) to already denied
* write access, so this is unlikely to fail.
*/
- if (unlikely(deny_write_access(new_exe_file)))
+ if (unlikely(exe_file_deny_write_access(new_exe_file)))
return -EACCES;
get_file(new_exe_file);
}
rcu_assign_pointer(mm->exe_file, new_exe_file);
if (old_exe_file) {
- allow_write_access(old_exe_file);
+ exe_file_allow_write_access(old_exe_file);
fput(old_exe_file);
}
return 0;
@@ -1323,7 +1323,7 @@ int replace_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
}
/* set the new file, lockless */
- ret = deny_write_access(new_exe_file);
+ ret = exe_file_deny_write_access(new_exe_file);
if (ret)
return -EACCES;
get_file(new_exe_file);
@@ -1335,7 +1335,7 @@ int replace_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
* write access while someone might open the file writable.
*/
mmap_read_lock(mm);
- allow_write_access(old_exe_file);
+ exe_file_allow_write_access(old_exe_file);
fput(old_exe_file);
mmap_read_unlock(mm);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 6.1.y 3/3] binfmt_misc: restore write access when removing an entry
2026-08-12 9:11 ` [PATCH 6.1.y 1/3] fsnotify: opt-in for permission events at file open time Sasha Levin
2026-08-12 9:11 ` [PATCH 6.1.y 2/3] fs: don't block write during exec on pre-content watched files Sasha Levin
@ 2026-08-12 9:11 ` Sasha Levin
1 sibling, 0 replies; 4+ messages in thread
From: Sasha Levin @ 2026-08-12 9:11 UTC (permalink / raw)
To: stable; +Cc: Christian Brauner, Sasha Levin
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit db1856ea9196cf6e015d12199a34c0b9313c7bfa ]
Registering an entry with the MISC_FMT_OPEN_FILE flag opens the
interpreter via open_exec() which denies write access to it for as
long as the entry exists. Removing the entry closes the interpreter
file via filp_close() but never restores write access, leaving the
inode's i_writecount permanently negative. Opening the interpreter
for writing keeps failing with ETXTBSY long after the entry is gone
until the inode is evicted from the inode cache.
Commit 90f601b497d7 ("binfmt_misc: restore write access before
closing files opened by open_exec()") fixed the same imbalance in the
error path of bm_register_write() but the actual removal path has
been leaking the write denial since the introduction of the flag.
Restore write access in put_binfmt_handler() before closing the
interpreter file.
Link: https://patch.msgid.link/20260710-work-binfmt_misc-locking-v3-1-a162f7cb58d6@kernel.org
Fixes: 948b701a607f ("binfmt_misc: add persistent opened binary handler for containers")
Cc: stable@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/binfmt_misc.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 05c2353094217..26ab9e5e15aa2 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -163,8 +163,10 @@ static Node *get_binfmt_handler(struct linux_binprm *bprm)
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);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-12 9:12 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-05 9:54 FAILED: patch "[PATCH] binfmt_misc: restore write access when removing an entry" failed to apply to 6.1-stable tree gregkh
2026-08-12 9:11 ` [PATCH 6.1.y 1/3] fsnotify: opt-in for permission events at file open time Sasha Levin
2026-08-12 9:11 ` [PATCH 6.1.y 2/3] fs: don't block write during exec on pre-content watched files Sasha Levin
2026-08-12 9:11 ` [PATCH 6.1.y 3/3] binfmt_misc: restore write access when removing an entry Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).