Merge tag 'vfs-7.4-rc3.fixes.2' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull more vfs fixes from Christian Brauner:
- inode: Let the shrinker reclaim inodes with I_METADATA_WRITEBACK like
any other clean inode and have evict() write out what the bit tracks
unless the inode is being deleted.
Since v7.3 ext2, ext4 without a journal, fat, udf and minix set
I_METADATA_WRITEBACK when they copy an inode into its buffer and only
fsync() and friends clear it again. inode_lru_isolate() took such
inodes off the LRU expecting something to put them back once the bit
was gone but nothing ever did. So they couldn't be reclaimed until
something fsynced them or the filesystem was unmounted.
On ext4 without a journal an atime update was enough to pin an inode,
and creating 60000 small files in a memory cgroup limited to 96M got
the task OOM killed after about 43000 of them. Now all 60000 get
created.
[86 lines not shown]
Merge tag 'loongarch-fixes-7.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
Pull LoongArch fixes from Huacai Chen:
"Fix several bugs in ACPI IOVT, KEXEC, Hibernation, BPF JIT and KVM"
* tag 'loongarch-fixes-7.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
LoongArch: KVM: Reject repeated PCH-PIC CTRL_INIT
LoongArch: KVM: Propagate real error code in kvm_pch_pic_create()
LoongArch: KVM: Clear device pointer in irqchip destroy callbacks
LoongArch: BPF: Make use of beqz and bnez for trampoline branches
LoongArch: BPF: Make arena support depend on 128-bit cmpxchg
LoongArch: Restore KFENCE pages through DMW on resume
LoongArch: kexec_file: Fix elf_headers memory leak in retry loop
LoongArch: kexec_file: Fix a modified cmdline leak
ACPI: LoongArch: Validate ACPI IOVT device entries
ACPI: LoongArch: Add checksum validation for ACPI IOVT table
ACPI: LoongArch: Fix incorrect pointer in acpi_iovt_init()
Merge tag 'v7.4-p2' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto fixes from Herbert Xu:
- Fix potential overflow from malformed keys in caam
- Fix use-after-free in essiv
- Fix potential dead-lock in ccp when combined with KVM changes in
mainline
* tag 'v7.4-p2' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
crypto: ccp - Make usage of sev_cmd_mutex more granular
crypto: essiv - fix use-after-free in AEAD path
crypto: caam - reject overlong RSA CRT parameters
Merge patch series "ns: fixes identifier fixes"
Christian Brauner <brauner at kernel.org> says:
The namespace_init hooks see a namespace id of zero because the id is
only allocated after the hook has run. The id is the only identifier of
a namespace that is never recycled. So it's what a bpf LSM wants to use
to track a namespace from namespace_init until namespace_free.
The inode number is recycled way too quickly for that. So allocate the
id in __ns_common_init() before the hook is called. Then ns_tree_add()
doesn't need to allocate ids anymore and ns_tree_add_raw() can go.
Landlock now logs that id instead of zero when it denies the creation of
a namespace.
* patches from https://patch.msgid.link/20261029-work-security-namespace_free-v2-0-65591dbba7b3@kernel.org:
nstree: drop ns_tree_add_raw()
ns: allocate the namespace id before the namespace_init hook
bpf: don't mark namespace_init and namespace_free arguments as trusted
[3 lines not shown]
nstree: drop ns_tree_add_raw()
Now that ns_tree_add() doesn't allocate an id anymore it does the same
thing as ns_tree_add_raw(). Switch the remaining ns_tree_add_raw() users
over to ns_tree_add() and drop it. Rename __ns_tree_add_raw() to
__ns_tree_add() while at it.
No functional changes.
Fixes: f675d2e95569 ("lsm: add LSM blob and hooks for namespaces")
Cc: stable at kernel.org # mainline only
Link: https://patch.msgid.link/20261029-work-security-namespace_free-v2-5-65591dbba7b3@kernel.org
Acked-by: Alexei Starovoitov <ast at kernel.org>
Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
ns: allocate the namespace id before the namespace_init hook
Currently the namespace id is allocated only after __ns_common_init()
has called the namespace_init LSM hook. Most namespace types allocate it
in ns_tree_add() right before the namespace is added to the namespace
trees. So the namespace_init hook always sees an id of zero.
The namespace id is the only identifier of a namespace that is never
recycled. A bpf LSM wants to use it to track a namespace from
namespace_init until namespace_free, e.g., by using it as the key into a
map that associates data with the namespace. The inode number doesn't
work for that as it is quickly recycled.
So allocate the id in __ns_common_init() before calling the
namespace_init hook. Every namespace then has its id by the time it is
added to the namespace trees. The initial namespaces still get their
fixed ids, either statically from NS_COMMON_INIT() or for init_net from
ns_common_init(). So ns_tree_add() doesn't need to allocate an id
anymore. Ids are still handed out in creation order so mnt_ns_loop()
[30 lines not shown]
bpf: don't mark namespace_init and namespace_free arguments as trusted
The bpf LSM marks the arguments of all hooks as trusted unless the hook
is listed in untrusted_lsm_hooks. That list was added in commit
c0c852dd1876 ("bpf: Do not mark certain LSM hook arguments as trusted")
for hooks that are called on objects that are only partially set up or
that are already on their way out. The namespace_init and namespace_free
hooks are exactly that but they aren't listed.
namespace_init is called from __ns_common_init() before the namespace
has been set up. It isn't in the namespace trees yet and for all types
but network namespaces even the owning user namespace isn't set yet. If
any LSM rejects the namespace or if anything after ns_common_init()
fails the namespace is freed right away without looking at its reference
count.
namespace_free is called from __ns_common_free() when the namespace is
torn down or when its initialization failed.
[13 lines not shown]
Merge patch series "splice: remove pipe buffer stealing"
Kiryl Shutsemau (Meta) <kas at kernel.org> says:
->try_steal() lets the consumer of a pipe buffer take its page instead
of copying the data. Two consumers use it:
- fuse, when a server splices a read reply into /dev/fuse with
SPLICE_F_MOVE: the page goes into the fuse file's page cache;
- virtio_console, which passes the page to the host.
The page can come from the page cache of another file, from a write()
into the pipe, or from vmsplice(SPLICE_F_GIFT). Stealing it takes page
cache folios out of their files, and turns pages into page cache folios
and back. That gets in the way of reading the page cache without folio
references [1] and of telling folios apart with a PG_folio flag. It
works only on pages that nothing else holds, for fuse only on clean,
unmapped, order-0 ones, and it has needed fixes again and again:
[36 lines not shown]
splice: replace nosteal_pipe_buf_ops with default_pipe_buf_ops
Without ->try_steal(), nosteal_pipe_buf_ops and default_pipe_buf_ops are
the same: generic_pipe_buf_release() and generic_pipe_buf_get().
Keep default_pipe_buf_ops, and use it in skb_splice_bits() and
fuse_dev_splice_read(). Export it in place of nosteal_pipe_buf_ops,
since fuse can be built as a module.
Signed-off-by: Kiryl Shutsemau (Meta) <kas at kernel.org>
Link: https://patch.msgid.link/20261110145241.536019-5-kas@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
splice: remove pipe buffer stealing
Nothing calls pipe_buf_try_steal() any more. Remove ->try_steal() from
struct pipe_buf_operations, its implementations and the exported
generic_pipe_buf_try_steal().
PIPE_BUF_FLAG_LRU and PIPE_BUF_FLAG_GIFT were set only for stealing, and
go too. page_cache_pipe_buf_release() did nothing but drop the page and
the LRU flag, so page cache and user page buffers use
generic_pipe_buf_release().
vmsplice() still accepts SPLICE_F_GIFT, and splice() SPLICE_F_MOVE.
Both were hints, and nothing acts on them now.
Suggested-by: Linus Torvalds <torvalds at linux-foundation.org>
Signed-off-by: Kiryl Shutsemau (Meta) <kas at kernel.org>
Link: https://patch.msgid.link/20261110145241.536019-4-kas@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
fuse: don't move pipe buffers into the page cache
A splice() into /dev/fuse with SPLICE_F_MOVE lets the reply to a read
request steal full pages from the pipe. Each stolen page replaces, in
the fuse file's page cache, the folio that the request allocated. The
page can be a page cache folio of another file, a page written into the
pipe, or a gifted user page.
Always copy. The server sees the same data, and the move was a hint
that splice() never promised to honour.
Keep advertising FUSE_SPLICE_MOVE. libfuse fails the mount of a
filesystem that asks for a capability the kernel does not offer.
Preparation for removing ->try_steal() from pipe buffers.
Suggested-by: David Hildenbrand (Arm) <david at kernel.org>
Suggested-by: Linus Torvalds <torvalds at linux-foundation.org>
Signed-off-by: Kiryl Shutsemau (Meta) <kas at kernel.org>
[4 lines not shown]
virtio_console: copy pipe buffers in splice_write()
pipe_to_sg() tries to steal the page of each pipe buffer and pass it to
the host as it is. When the steal fails, it copies the data into a page
of its own.
Pages written into the pipe with write(), gifted user pages and page
cache pages can be stolen. The ftrace ring buffer pages that
virtio-trace splices cannot, so that in-tree user always gets the copy.
Always copy. The data that reaches the host does not change.
Preparation for removing ->try_steal() from pipe buffers.
Suggested-by: Linus Torvalds <torvalds at linux-foundation.org>
Signed-off-by: Kiryl Shutsemau (Meta) <kas at kernel.org>
Link: https://patch.msgid.link/20261110145241.536019-2-kas@kernel.org
Acked-by: Zi Yan <ziy at nvidia.com>
Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
fs/adfs: bound directory entry name length in adfs_fplus_getnext()
adfs_fplus_getnext() reads the per-entry name length bigdirobnamelen
straight from the on-disk big directory and passes it to
adfs_dir_copyfrom() as the copy length into obj->name[], a fixed
ADFS_MAX_NAME_LEN (260) byte buffer. adfs_dir_copyfrom() only bounds
the copy against the number of directory buffers, not the size of the
destination, so a crafted image with bigdirobnamelen larger than the
buffer overflows the stack-allocated object_info::name that
adfs_fplus_iterate() passes in.
adfs_object_fixup() may additionally append a four byte ",xyz" filetype
suffix, so the accepted length must also leave room for that.
The old-style directory parser (dir_f.c) already clamps names to
ADFS_F_NAME_LEN, and adfs_fplus_validate_header() validates the header
name fields, but the per-entry name length in the big directory format
was never checked. Reject over-long entries, using -EIO as elsewhere
in this file for a corrupt big directory.
[8 lines not shown]
Merge patch series "dcache: fixes for mountpoints racing d_invalidate() and umount"
Christian Brauner <brauner at kernel.org> says:
d_set_mounted() hasn't bumped the seqcount of rename_lock since v6.17
and the lockless walk in d_invalidate() neither waits for nor retries
against a concurrent mount anymore.
So a mount below a directory that is being invalidated can end up below
the unhashed directory. Nobody can reach it anymore and it pins the
subtree until the mount namespace goes away. Giving d_set_mounted() a
seqlock of its own that d_invalidate() waits on after its unhash closes
that without going back to bumping the seqcount.
The second one is from v7.3 and was backported to 7.2.6. do_one_tree()
now takes every secondary root off ->s_roots before its dput(). If
another thread is evicting the root at the same time umount loses the
eviction to it and doesn't wait for it. That ends in busy inodes after
unmount and an iput() on a dead superblock.
[21 lines not shown]
dcache: let umount find a disconnected ex-mountpoint
When a mount goes away the reference to its mountpoint is dropped with
dput_to_list() and namespace_unlock() evicts the dentry after dropping
namespace_sem. Nothing pins the filesystem at that point so it can be
unmounted at the same time. That's fine as long as
shrink_dcache_for_umount() finds the dentry. It then either evicts it
itself or waits for the eviction to finish.
But it can't find a disconnected root as those are neither in the tree
nor on ->s_roots. And they can be mounted on:
fd = open_by_handle_at(mnt_fd, handle of a file with no dentry, O_PATH);
tree = open_tree(AT_FDCWD, "/tmp/x", OPEN_TREE_CLONE);
move_mount(tree, "", fd, "", MOVE_MOUNT_F_EMPTY_PATH |
MOVE_MOUNT_T_EMPTY_PATH);
close(fd);
thread A thread B
[26 lines not shown]
dcache: wait for a racing eviction of a secondary root
Commit e9895609cb7f ("wind ->s_roots via ->d_sib instead of ->d_hash")
keeps a secondary root on ->s_roots until dentry_unlist() so that
shrink_dcache_for_umount() can find one that another thread is evicting
and wait for it. But do_one_tree() takes every root off the list before
its dput() which breaks that:
thread A umount
dentry_kill(root), refcount is 0
lock_for_kill()
spin_trylock(->i_lock) fails
spin_unlock(->d_lock)
shrink_dcache_for_umount()
dget_dlock(root)
do_one_tree(root)
unlink_secondary_root(root)
spin_lock(->i_lock)
dput(root), refcount is 0
[27 lines not shown]
dcache: let d_invalidate() wait for a d_set_mounted() in flight
d_invalidate() and d_set_mounted() are supposed to exclude each other.
Either the mount fails with -ENOENT because an ancestor of the
mountpoint was unhashed or d_invalidate() finds the mountpoint and
detaches the mount. d_invalidate() unhashes the dentry first and then
searches the subtree with d_walk() which starts out lockless and only
looks at the seqcount of rename_lock.
Since d_set_mounted() switched to read_seqlock_excl() nothing makes that
walk wait or retry:
CPU0: mount on A/M CPU1: d_invalidate(A)
d_set_mounted(M)
read_seqlock_excl(&rename_lock)
A is hashed, go on
__d_drop(A)
shrink_dcache_parent(A)
d_walk(A, find_submount)
[65 lines not shown]
Merge patch series "fs: reclaim inodes with I_METADATA_WRITEBACK"
Christian Brauner <brauner at kernel.org> says:
Since v7.3 ext2, ext4 without a journal, fat, udf and minix set
I_METADATA_WRITEBACK when they copy an inode into its buffer and only
fsync() and friends clear it again.
inode_lru_isolate() treats it like any other state bit and takes the
inode off the LRU, expecting something to put it back once the bit is
gone. Nothing ever does. So these inodes can't be reclaimed until
something fsyncs them or the filesystem is unmounted. That's a DoS.
On ext4 without a journal an atime update is enough to pin an inode, and
creating 60000 small files in a memory cgroup limited to 96M gets the
task OOM killed after about 43000 of them.
The original provided fix was quite ugly. It handed such inodes from
inode_lru_isolate() to a per-sb work item with a reference held, synced
[57 lines not shown]
fat: drop mmb_sync() from fat_evict_inode()
evict() writes out what I_METADATA_WRITEBACK tracks before it calls
->evict_inode() and since mmb_mark_buffer_dirty() sets the bit that
includes the tracked metadata buffers. So there's nothing left for
fat_evict_inode() to sync. The write-out happens before
fat_free_eofblocks() updates the directory entry again, so that update
stays as asynchronous as it is now.
Link: https://patch.msgid.link/20261109-work-inode-metadata_writeback-v3-14-91ac6c024018@kernel.org
Reviewed-by: Jan Kara <jack at suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
udf: drop mmb_sync() from udf_evict_inode()
evict() writes out what I_METADATA_WRITEBACK tracks before it calls
->evict_inode() and since mmb_mark_buffer_dirty() sets the bit that
includes the tracked metadata buffers. So there's nothing left for
udf_evict_inode() to sync for an inode that isn't deleted.
Link: https://patch.msgid.link/20261109-work-inode-metadata_writeback-v3-13-91ac6c024018@kernel.org
Reviewed-by: Jan Kara <jack at suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
minix: drop mmb_sync() from minix_evict_inode()
evict() writes out what I_METADATA_WRITEBACK tracks before it calls
->evict_inode() and since mmb_mark_buffer_dirty() sets the bit that
includes the tracked metadata buffers. So there's nothing left for
minix_evict_inode() to sync.
Link: https://patch.msgid.link/20261109-work-inode-metadata_writeback-v3-12-91ac6c024018@kernel.org
Reviewed-by: Jan Kara <jack at suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
ext4: drop mmb_sync() from ext4_evict_inode()
evict() writes out what I_METADATA_WRITEBACK tracks before it calls
->evict_inode() and since mmb_mark_buffer_dirty() sets the bit that
includes the tracked metadata buffers. So there's nothing left for
ext4_evict_inode() to sync without a journal, and with a journal there
are no tracked buffers.
Link: https://patch.msgid.link/20261109-work-inode-metadata_writeback-v3-11-91ac6c024018@kernel.org
Reviewed-by: Jan Kara <jack at suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
ext2: drop mmb_sync() from ext2_evict_inode()
evict() writes out what I_METADATA_WRITEBACK tracks before it calls
->evict_inode() and since mmb_mark_buffer_dirty() sets the bit that
includes the tracked metadata buffers. So there's nothing left for
ext2_evict_inode() to sync.
Link: https://patch.msgid.link/20261109-work-inode-metadata_writeback-v3-10-91ac6c024018@kernel.org
Reviewed-by: Jan Kara <jack at suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
fs: don't strand I_METADATA_WRITEBACK inodes outside the LRU
Since commit c474bc56b6d1 ("fs: Provide way for filesystem to wait for
metadata writeback") ext2, ext4 without a journal, fat, udf and minix
set I_METADATA_WRITEBACK on an inode whose metadata was copied into a
buffer that might not have reached the disk yet. Only data integrity
writeback, i.e. fsync() and friends, clears it again. The flusher and
sync(2) leave it alone.
inode_lru_isolate() treats every state bit other than I_REFERENCED as a
reason not to reclaim the inode right now. It takes the inode off the
LRU and relies on iput(), writeback completion or the removal of the
last page from the page cache to put it back once the reason is gone.
But I_METADATA_WRITEBACK doesn't go away on its own. iput() puts the
inode back on the LRU with the bit still set and the next scan takes it
off again. So neither memory pressure nor drop_caches can free these
inodes. Only fsync() and friends or unmounting the filesystem get rid
of them.
[36 lines not shown]
fs: set I_METADATA_WRITEBACK in mmb_mark_buffer_dirty()
ext2, ext4 without a journal, fat, udf and minix track the metadata
buffers of an inode in a mapping_metadata_bhs list and sync them from
->sync_inode_metadata() and ->evict_inode(). The inode block itself is
only tracked by I_METADATA_WRITEBACK which ->write_inode() sets after
copying the inode into its buffer.
Set the bit in mmb_mark_buffer_dirty() as well so that it covers all
the metadata an inode may still have to write out. Set it after the
buffer is on the list. An fsync() that sees the bit then also finds the
buffer when it walks the list, and one that cleared the bit before we
set it leaves it set for the next one.
The inode itself may never have been dirtied. fat for example tracks
the FAT buffers on a private inode that nothing marks dirty. So attach
the inode to a wb before setting the bit, the way ext4_mark_iloc_dirty()
does, or writeback_single_inode() has no wb to lock once evict() syncs
it.
[9 lines not shown]
udf: don't allocate the inode block in udf_sync_inode_metadata()
udf_sync_inode_metadata() looks the block that holds the inode up with
sb_getblk() which allocates a buffer for it if it isn't cached. But a
block that isn't cached is neither dirty nor under writeback, so there's
nothing to write or to wait for and the buffer just gets thrown away
again.
That allocation is also something we can't afford once inode eviction
calls ->sync_inode_metadata() from reclaim. So look the block up with
sb_find_get_block_nonatomic() instead.
Cc: stable at vger.kernel.org # v7.3
Reviewed-by: Jan Kara <jack at suse.cz>
Link: https://patch.msgid.link/20261109-work-inode-metadata_writeback-v3-7-91ac6c024018@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
minix: don't read the inode block in minix_sync_inode_metadata()
minix_sync_inode_metadata() looks the inode block up with
minix_V1_raw_inode() or minix_V2_raw_inode() which read it from disk if
it isn't cached. But a block that isn't cached is neither dirty nor
under writeback, so there's nothing to write or to wait for.
That read is also something we can't afford once inode eviction calls
->sync_inode_metadata() from reclaim. So look the block up with
sb_find_get_block_nonatomic() instead.
Cc: stable at vger.kernel.org # v7.3
Reviewed-by: Jan Kara <jack at suse.cz>
Link: https://patch.msgid.link/20261109-work-inode-metadata_writeback-v3-6-91ac6c024018@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
minix: add minix_inode_block() helper
Move the lookup of the block that holds an inode out of
minix_V1_raw_inode() and minix_V2_raw_inode() into a helper.
minix_sync_inode_metadata() is going to use it to find the block
without reading it from disk.
No functional changes.
Cc: stable at vger.kernel.org # v7.3
Reviewed-by: Jan Kara <jack at suse.cz>
Link: https://patch.msgid.link/20261109-work-inode-metadata_writeback-v3-5-91ac6c024018@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
ext4: don't read the inode block in ext4_sync_inode_metadata()
Without a journal ext4_sync_inode_metadata() looks the inode table
block up with __ext4_get_inode_loc_noinmem() which reads it from disk,
with readahead of the inode table on top, if it isn't cached. But a
block that isn't cached is neither dirty nor under writeback, so there's
nothing to write or to wait for.
That read is also something we can't afford once inode eviction calls
->sync_inode_metadata() from reclaim. So look the block up with
ext4_get_inode_loc_noio() instead and treat -EAGAIN as nothing to do.
Note that ext4_get_inode_loc_noio() also returns -EAGAIN for a block
that isn't uptodate. Such a block is being read or failed to be read
and can't be dirty either. A block whose write failed still counts as
uptodate for ext4_buffer_uptodate() so the write error still gets
reported.
Suggested-by: Jan Kara <jack at suse.cz>
[4 lines not shown]
ext4: use sb_find_get_block_nonatomic() in ext4_get_inode_loc_noio()
ext4_get_inode_loc_noio() looks the inode table block up with
sb_find_get_block(). That's the atomic lookup. It serializes against
try_to_free_buffers() with i_private_lock instead of the folio lock and
gives up if the folio is being migrated. So it can report the block as
not cached while it is.
For ext4_fc_snapshot_inode() that only means falling back to a full
commit. But ext4_sync_inode_metadata() is going to use
ext4_get_inode_loc_noio() to find the inode block that fsync() has to
write out and there a dirty block must not be skipped.
ext4_fc_snapshot_inode() is the only caller and it can sleep. It runs
under jbd2_journal_lock_updates() and allocates the snapshot with
GFP_NOFS. So use sb_find_get_block_nonatomic() which takes the folio
lock and waits for the migration instead.
Suggested-by: Jan Kara <jack at suse.cz>
[4 lines not shown]