[GIT PULL for v7.3] vfs fixes

From: Christian Brauner

Date: Fri Oct 16 2026 - 06:28:03 EST


Hey Linus,

/* Summary */

This contains last fixes for the current development cycle:

- Fix a range of use-after-frees during rcu pathwalk caused by non-rcu
frees. Whatever ->permission(), ->d_revalidate(), ->get_link(),
->d_hash() and ->d_compare() read in rcu mode has to be freed after a
grace period. umount(2) hides most of it because namespace_unlock()
waits for one, but a chdir() out of a lazily unmounted directory or
the close() of the last file on it drops the last reference without.

* ext4_get_link() reads the sbi and the extent status counters for a
symlink stored in a data block. Both are freed after a grace period
now.

* The unicode map of casefolded ext4, f2fs and tmpfs was freed under
generic_ci_d_hash() and generic_ci_d_compare().

* ntfs3 with nocase freed its sbi and mount options under its dentry
hash and compare. A remount freed the old options right away too.

* eventfs freed an eventfs_inode after an SRCU grace period only
while tracefs_d_revalidate() reads it under rcu_read_lock().

* afs and 9p are only saved by the grace period their private bdi
gets in bdi_unregister(). They stop depending on it.

* create_ipc_ns() leaked the mqueue mount and its superblock on a
late failure. A long-term mount needs kern_unmount().

- Don't let idle threads pin the initramfs. The idle threads of the
secondary cpus are forked from PID 1 with a private copy of its
fs_struct, aren't on the task list so pivot_root() never moves them
and never exit. So the initramfs stayed pinned forever on every
machine with more than one cpu, 70 to 150 MB in the reports. They
share init_fs now like init_task does.

- A mount that copy_tree() leaves out can't take over a lock.
copy_tree() drops mounts of mount namespace files from the copies it
makes for unshare(CLONE_NEWNS) and propagation without looking at
MNT_LOCKED. So root in a user namespace could bind a child's
/proc/<pid>/ns/mnt beneath a locked cover, let it take the lock over,
unshare(CLONE_NEWNS) and read the file. copy_tree() refuses with
EPERM now and the move beneath a locked mount is refused up front.

- Revert "namei: don't reveal overmounted entries in refwalk" from the
rc7 fixes. The bug class is bigger than that patch.

- namei: lookup_fast_for_open() checked ->d_inode while
traverse_mounts() checks the type in d_flags, which is set second, so
a refwalk racing the instantiation could fail an O_CREAT open with
ENOENT. Use d_is_negative() in both places.

- Drop the smp_mb()s in mntput_no_expire_slowpath() and do_umount()
that mnt_get_count()'s own barrier made redundant.

- fsnotify: a mark added while fsnotify_destroy_marks() walks the
connector could be missed and the connector detached, so an fdinfo
read called igrab(NULL). New marks are refused during teardown.

- pipe: a failed second fasync enable on an O_RDWR FIFO removed the
existing reader entry and cleared FASYNC while the writer entry
stayed, a use-after-free in send_sigio() later.

- watch_queue: post_one_notification() could see nr_notes before the
note pool behind it and dereference a NULL array. An unprivileged
user can trigger that with a key watch. Publish nr_notes last.

- pid_namespace: zap_pid_ns_processes() waits without bound for a
tracer outside the namespace to reap its zombies and neither wait
was freezable, so every suspend attempt failed.

- exit: is_child_subreaper and has_child_subreaper shared a word with
other bitfields written without a common lock, so racing prctl()s
lost a bit. They are separate bools now.

- autofs: a notification write that failed on a pipe the daemon had
already replaced put the superblock into catatonic mode again and
closed the replacement. Only do that for the current pipe.

- ovl: reject a lowerdir ending with an unescaped backslash with EINVAL
instead of a confusing ENOENT later.

- ocfs2/dlm: take dlm_reco_state_lock when the debugfs state file walks
the recovery participant list.

- samples/pidfd: fix the userprogs typo that kept pidfd-metadata from
being built.

/* Conflicts */

Merge conflicts with mainline
=============================

No known conflicts.

Merge conflicts with other trees
================================

No known conflicts.

The following changes since commit 24a19b953e2a3d0ea5a8c4951a0ab8f32720c907:

Linux 7.3-rc7 (2026-10-11 20:04:55 -0700)

are available in the Git repository at:

git@xxxxxxxxxxxxxxxxxxx:pub/scm/linux/kernel/git/vfs/vfs tags/vfs-7.3-rc8.fixes

for you to fetch changes up to 214897acc8c2e5d6b63189d23ccaed6fa2af45a9:

Revert "namei: don't reveal overmounted entries in refwalk" (2026-10-16 10:50:57 +0200)

----------------------------------------------------------------
vfs-7.3-rc8.fixes

Please consider pulling these changes from the signed vfs-7.3-rc8.fixes tag.

Thanks!
Christian

----------------------------------------------------------------
Aviv Vaknin (1):
pid_namespace: make zap_pid_ns_processes() freezable

Cen Zhang (1):
ocfs2/dlm: Protect the recovery list during debugfs reads

Cen Zhang (Microsoft) (1):
watch_queue: Fix note pool publication race in watch_queue_set_size()

Christian Brauner (19):
ext4: free the sbi after a grace period
afs: free the super info after a grace period
9p: free the session after a grace period
eventfs: free the eventfs_inode after an rcu grace period too
ipc: drop the mqueue mount with kern_unmount() on setup failure
unicode: free the map after a grace period
ntfs3: free the sbi after a grace period
ntfs3: free replaced mount options after a grace period
Merge patch series "fs: fix a range of UAFs during rcu pathwalk caused by non-rcu frees"
fs: drop the smp_mb()s that mnt_get_count() made redundant
Merge patch series "fs: drop the smp_mb()s that mnt_get_count() made redundant"
fs: pass flags to copy_fs()
namei: test for a negative dentry the way traverse_mounts() does
namespace: a mount that copy_tree() leaves out can't take over a lock
fs: let idle threads share init_fs
selftests/filesystems: test that a mntns file can't take over a lock
Merge patch series "fs: don't let idle threads pin the initramfs"
Merge patch series "namespace: a mount that copy_tree() leaves out can't take over a lock"
Revert "namei: don't reveal overmounted entries in refwalk"

Guanglei Zhu (1):
ovl: reject lowerdir ending with unescaped backslash

Kyle Zeng (2):
pipe: preserve existing fasync readers on writer setup failure
fsnotify: prevent mark additions during connector teardown

Nickolai Zeldovich (1):
exit: fix lost-update race on the child_subreaper bitfields

Sasha Levin (1):
samples: pidfd: fix userprogs typo

Sung Byeongchan (1):
autofs: ignore notification errors from a replaced pipe

fs/9p/v9fs.h | 1 +
fs/9p/vfs_super.c | 4 +-
fs/afs/internal.h | 2 +
fs/afs/super.c | 2 +-
fs/autofs/waitq.c | 25 ++++-
fs/ext4/ext4.h | 2 +
fs/ext4/extents-test.c | 2 +
fs/ext4/extents.c | 1 +
fs/ext4/extents_status.c | 7 +-
fs/ext4/extents_status.h | 1 +
fs/ext4/super.c | 13 ++-
fs/namei.c | 32 +-----
fs/namespace.c | 33 ++++--
fs/notify/mark.c | 11 ++
fs/ntfs3/dir.c | 13 ++-
fs/ntfs3/ntfs_fs.h | 3 +
fs/ntfs3/super.c | 49 ++++++---
fs/ocfs2/dlm/dlmcommon.h | 2 +
fs/ocfs2/dlm/dlmdebug.c | 5 +-
fs/ocfs2/dlm/dlmrecovery.c | 2 +-
fs/overlayfs/params.c | 3 +
fs/pipe.c | 6 +-
fs/tracefs/event_inode.c | 10 +-
fs/unicode/utf8-core.c | 21 +++-
include/linux/fsnotify_backend.h | 1 +
include/linux/sched/signal.h | 4 +-
include/linux/unicode.h | 1 +
ipc/namespace.c | 2 +-
kernel/exit.c | 2 +-
kernel/fork.c | 20 +++-
kernel/pid_namespace.c | 2 +-
kernel/watch_queue.c | 11 +-
samples/pidfd/Makefile | 2 +-
.../umount_propagation/locked_mount_test.c | 122 +++++++++++++++++++++
34 files changed, 325 insertions(+), 92 deletions(-)