linux-stable/fs
Jiufei Xue b187c97611 fs: writeback: fix use-after-free in __mark_inode_dirty()
[ Upstream commit d02d2c98d2 ]

An use-after-free issue occurred when __mark_inode_dirty() get the
bdi_writeback that was in the progress of switching.

CPU: 1 PID: 562 Comm: systemd-random- Not tainted 6.6.56-gb4403bd46a8e #1
......
pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : __mark_inode_dirty+0x124/0x418
lr : __mark_inode_dirty+0x118/0x418
sp : ffffffc08c9dbbc0
........
Call trace:
 __mark_inode_dirty+0x124/0x418
 generic_update_time+0x4c/0x60
 file_modified+0xcc/0xd0
 ext4_buffered_write_iter+0x58/0x124
 ext4_file_write_iter+0x54/0x704
 vfs_write+0x1c0/0x308
 ksys_write+0x74/0x10c
 __arm64_sys_write+0x1c/0x28
 invoke_syscall+0x48/0x114
 el0_svc_common.constprop.0+0xc0/0xe0
 do_el0_svc+0x1c/0x28
 el0_svc+0x40/0xe4
 el0t_64_sync_handler+0x120/0x12c
 el0t_64_sync+0x194/0x198

Root cause is:

systemd-random-seed                         kworker
----------------------------------------------------------------------
___mark_inode_dirty                     inode_switch_wbs_work_fn

  spin_lock(&inode->i_lock);
  inode_attach_wb
  locked_inode_to_wb_and_lock_list
     get inode->i_wb
     spin_unlock(&inode->i_lock);
     spin_lock(&wb->list_lock)
  spin_lock(&inode->i_lock)
  inode_io_list_move_locked
  spin_unlock(&wb->list_lock)
  spin_unlock(&inode->i_lock)
                                    spin_lock(&old_wb->list_lock)
                                      inode_do_switch_wbs
                                        spin_lock(&inode->i_lock)
                                        inode->i_wb = new_wb
                                        spin_unlock(&inode->i_lock)
                                    spin_unlock(&old_wb->list_lock)
                                    wb_put_many(old_wb, nr_switched)
                                      cgwb_release
                                      old wb released
  wb_wakeup_delayed() accesses wb,
  then trigger the use-after-free
  issue

Fix this race condition by holding inode spinlock until
wb_wakeup_delayed() finished.

Signed-off-by: Jiufei Xue <jiufei.xue@samsung.com>
Link: https://lore.kernel.org/20250728100715.3863241-1-jiufei.xue@samsung.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2025-09-09 18:50:17 +02:00
..
9p
adfs
affs affs: don't write overlarge OFS data block size fields 2025-04-10 14:32:03 +02:00
afs afs: Fix the server_list to unuse a displaced server rather than putting it 2025-03-13 12:50:56 +01:00
autofs
befs
bfs
btrfs btrfs: populate otime when logging an inode item 2025-08-28 16:24:32 +02:00
cachefiles
ceph ceph: fix possible integer overflow in ceph_zero_objects() 2025-07-10 15:57:34 +02:00
cifs smb: client: fix use-after-free in crypt_message when using async crypto 2025-08-28 16:24:31 +02:00
coda
configfs configfs: Do not override creating attribute file failure in populate_attrs() 2025-06-27 11:05:22 +01:00
cramfs
crypto
debugfs
devpts
dlm dlm: make tcp still work in multi-link env 2025-06-04 14:37:56 +02:00
ecryptfs
efivarfs efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare 2025-09-04 14:28:46 +02:00
efs
erofs erofs: fix incorrect symlink detection in fast symlink 2025-01-09 13:28:30 +01:00
exfat exfat: fix double free in delayed_free 2025-06-27 11:05:28 +01:00
exportfs
ext2 ext2: Handle fiemap on empty files to prevent EINVAL 2025-08-28 16:24:17 +02:00
ext4 ext4: fix hole length calculation overflow in non-extent inodes 2025-08-28 16:24:28 +02:00
f2fs f2fs: fix to avoid out-of-boundary access in dnode page 2025-08-28 16:24:36 +02:00
fat
freevxfs
fscache
fuse virtiofs: add filesystem context source name check 2025-05-02 07:44:14 +02:00
gfs2 gfs2: move msleep to sleepable context 2025-06-27 11:05:23 +01:00
hfs hfs: fix not erasing deleted b-tree node issue 2025-08-28 16:24:16 +02:00
hfsplus hfsplus: don't use BUG_ON() in hfsplus_create_attributes_file() 2025-08-28 16:24:16 +02:00
hostfs
hpfs
hugetlbfs mm: update memfd seal write check to include F_SEAL_WRITE 2025-08-28 16:24:30 +02:00
iomap
isofs isofs: Verify inode mode when loading from disk 2025-08-28 16:23:59 +02:00
jbd2 jbd2: prevent softlockup in jbd2_log_do_checkpoint() 2025-08-28 16:24:29 +02:00
jffs2 jffs2: check jffs2_prealloc_raw_node_refs() result in few other places 2025-06-27 11:05:34 +01:00
jfs jfs: upper bound check of tree index in dbAllocAG 2025-08-28 16:24:23 +02:00
kernfs
ksmbd smb: server: Fix extension string in ksmbd_extract_shortname() 2025-08-28 16:24:31 +02:00
lockd
minix
netfs
nfs NFS: Fix a race when updating an existing write 2025-09-04 14:28:44 +02:00
nfs_common
nfsd NFSD: detect mismatch of file handle and delegation stateid in OPEN op 2025-08-28 16:24:15 +02:00
nilfs2 nilfs2: reject invalid file types when reading inodes 2025-08-28 16:24:05 +02:00
nls
notify
ntfs
ntfs3 fs/ntfs3: correctly create symlink for relative path 2025-08-28 16:24:17 +02:00
ocfs2 ocfs2: fix possible memory leak in ocfs2_finish_quota_recovery 2025-06-27 11:05:14 +01:00
omfs
openpromfs
orangefs fs/orangefs: use snprintf() instead of sprintf() 2025-08-28 16:24:23 +02:00
overlayfs ovl: Check for NULL d_inode() in ovl_dentry_upper() 2025-07-10 15:57:34 +02:00
proc fs/proc: do_task_stat: use __for_each_thread() 2025-07-17 18:30:47 +02:00
pstore pstore/blk: trivial typo fixes 2025-03-13 12:49:51 +01:00
qnx4
qnx6
quota
ramfs
reiserfs
romfs
smbfs_common
squashfs squashfs: fix memory leak in squashfs_fill_super 2025-08-28 16:24:34 +02:00
sysfs
sysv
tracefs
ubifs ubifs: skip dumping tnc tree when zroot is null 2025-03-13 12:50:11 +01:00
udf udf: Fix directory iteration for longer tail extents 2025-09-04 14:28:44 +02:00
ufs
unicode Revert "unicode: Don't special case ignorable code points" 2024-12-14 19:51:44 +01:00
vboxsf vboxsf: fix building with GCC 15 2025-04-10 14:31:50 +02:00
verity
xfs xfs: do not propagate ENODATA disk errors into xattr code 2025-09-04 14:28:48 +02:00
zonefs
aio.c
anon_inodes.c
attr.c
bad_inode.c
binfmt_aout.c
binfmt_elf_fdpic.c
binfmt_elf.c
binfmt_flat.c binfmt_flat: Fix integer overflow bug on 32 bit systems 2025-03-13 12:50:24 +01:00
binfmt_misc.c
binfmt_script.c
buffer.c fs/buffer: fix use-after-free when call bh_read() helper 2025-08-28 16:24:34 +02:00
char_dev.c
compat_binfmt_elf.c
coredump.c coredump: hand a pidfd to the usermode coredump helper 2025-06-04 14:38:07 +02:00
d_path.c
dax.c
dcache.c
direct-io.c
drop_caches.c
eventfd.c
eventpoll.c eventpoll: Fix semi-unbounded recursion 2025-08-28 16:24:15 +02:00
exec.c
fcntl.c
fhandle.c
file_table.c fs: fix proc_handler for sysctl_nr_open 2025-03-13 12:49:50 +01:00
file.c alloc_fdtable(): change calling conventions. 2025-08-28 16:24:39 +02:00
filesystems.c fs/filesystems: Fix potential unsigned integer underflow in fs_name() 2025-06-27 11:05:20 +01:00
fs_context.c
fs_parser.c
fs_pin.c
fs_struct.c
fs_types.c
fs-writeback.c fs: writeback: fix use-after-free in __mark_inode_dirty() 2025-09-09 18:50:17 +02:00
fsopen.c
init.c
inode.c fs: move inode sysctls to its own file 2025-03-13 12:49:50 +01:00
internal.h
ioctl.c
Kconfig nfs: add missing selections of CONFIG_CRC32 2025-05-02 07:44:12 +02:00
Kconfig.binfmt
kernel_read_file.c
libfs.c better lockdep annotations for simple_recursive_removal() 2025-08-28 16:24:16 +02:00
locks.c
Makefile
mbcache.c
mount.h
mpage.c
namei.c fuse: don't truncate cached, mutated symlink 2025-04-10 14:31:51 +02:00
namespace.c use uniform permission checks for all mount propagation changes 2025-08-28 16:24:34 +02:00
no-block.c
nsfs.c
open.c
pipe.c
pnode.c
pnode.h
posix_acl.c
proc_namespace.c
read_write.c
readdir.c
remap_range.c
select.c select: Fix unbalanced user_access_end() 2025-03-13 12:49:51 +01:00
seq_file.c
signalfd.c
splice.c
stack.c
stat.c
statfs.c
super.c
sync.c
timerfd.c
userfaultfd.c
utimes.c
xattr.c