Baokun Li
d40c192e11
quota: fix dqput() to follow the guarantees dquot_srcu should provide
...
[ Upstream commit dabc8b20756601b9e1cc85a81d47d3f98ed4d13a ]
The dquot_mark_dquot_dirty() using dquot references from the inode
should be protected by dquot_srcu. quota_off code takes care to call
synchronize_srcu(&dquot_srcu) to not drop dquot references while they
are used by other users. But dquot_transfer() breaks this assumption.
We call dquot_transfer() to drop the last reference of dquot and add
it to free_dquots, but there may still be other users using the dquot
at this time, as shown in the function graph below:
cpu1 cpu2
_________________|_________________
wb_do_writeback CHOWN(1)
...
ext4_da_update_reserve_space
dquot_claim_block
...
dquot_mark_dquot_dirty // try to dirty old quota
test_bit(DQ_ACTIVE_B, &dquot->dq_flags) // still ACTIVE
if (test_bit(DQ_MOD_B, &dquot->dq_flags))
// test no dirty, wait dq_list_lock
...
dquot_transfer
__dquot_transfer
dqput_all(transfer_from) // rls old dquot
dqput // last dqput
dquot_release
clear_bit(DQ_ACTIVE_B, &dquot->dq_flags)
atomic_dec(&dquot->dq_count)
put_dquot_last(dquot)
list_add_tail(&dquot->dq_free, &free_dquots)
// add the dquot to free_dquots
if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags))
add dqi_dirty_list // add released dquot to dirty_list
This can cause various issues, such as dquot being destroyed by
dqcache_shrink_scan() after being added to free_dquots, which can trigger
a UAF in dquot_mark_dquot_dirty(); or after dquot is added to free_dquots
and then to dirty_list, it is added to free_dquots again after
dquot_writeback_dquots() is executed, which causes the free_dquots list to
be corrupted and triggers a UAF when dqcache_shrink_scan() is called for
freeing dquot twice.
As Honza said, we need to fix dquot_transfer() to follow the guarantees
dquot_srcu should provide. But calling synchronize_srcu() directly from
dquot_transfer() is too expensive (and mostly unnecessary). So we add
dquot whose last reference should be dropped to the new global dquot
list releasing_dquots, and then queue work item which would call
synchronize_srcu() and after that perform the final cleanup of all the
dquots on releasing_dquots.
Fixes: 4580b30ea8 ("quota: Do not dirty bad dquots")
Suggested-by: Jan Kara <jack@suse.cz>
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Message-Id: <20230630110822.3881712-5-libaokun1@huawei.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2023-09-23 10:59:43 +02:00
..
9p
9p: missing chunk of "fs/9p: Don't update file type when updating file attributes"
2022-06-22 14:11:02 +02:00
adfs
affs
affs: initialize fsdata in affs_truncate()
2023-02-06 07:52:36 +01:00
afs
afs: Fix vlserver probe RTT handling
2023-06-21 15:44:12 +02:00
autofs
befs
bfs
btrfs
btrfs: fix BUG_ON condition in btrfs_cancel_balance
2023-08-30 16:27:15 +02:00
cachefiles
ceph
ceph: defer stopping mdsc delayed_work
2023-08-11 11:54:01 +02:00
cifs
new helper: lookup_positive_unlocked()
2023-09-23 10:59:40 +02:00
coda
coda: Avoid partial allocation of sig_inputArgs
2023-03-11 16:43:56 +01:00
configfs
configfs: fix possible memory leak in configfs_create_dir()
2023-01-18 11:41:09 +01:00
cramfs
crypto
debugfs
new helper: lookup_positive_unlocked()
2023-09-23 10:59:40 +02:00
devpts
fsnotify: fix fsnotify hooks in pseudo filesystems
2022-02-01 17:24:34 +01:00
dlm
fs: dlm: fix mismatch of plock results from userspace
2023-08-30 16:27:21 +02:00
ecryptfs
efivarfs
efs
erofs
erofs: ensure that the post-EOF tails are all zeroed
2023-09-23 10:59:36 +02:00
exportfs
ext2
ext2: Drop fragment support
2023-08-11 11:53:59 +02:00
ext4
ext4: fix to check return value of freeze_bdev() in ext4_shutdown()
2023-08-11 11:53:47 +02:00
f2fs
Revert "f2fs: fix potential corruption when moving a directory"
2023-07-27 08:37:26 +02:00
fat
treewide: Remove uninitialized_var() usage
2023-06-09 10:29:01 +02:00
freevxfs
fscache
fuse
fuse: revalidate: don't invalidate if interrupted
2023-07-27 08:37:40 +02:00
gfs2
gfs2: Fix possible data races in gfs2_show_options()
2023-08-30 16:27:10 +02:00
hfs
hfs: fix missing hfs_bnode_get() in __hfs_bnode_create
2023-03-11 16:43:59 +01:00
hfsplus
treewide: Remove uninitialized_var() usage
2023-06-09 10:29:01 +02:00
hostfs
hpfs
hugetlbfs
hugetlbfs: fix null-ptr-deref in hugetlbfs_parse_param()
2023-01-18 11:41:38 +01:00
iomap
iomap: iomap_write_failed fix
2022-06-14 18:11:36 +02:00
isofs
treewide: Remove uninitialized_var() usage
2023-06-09 10:29:01 +02:00
jbd2
jbd2: Fix wrongly judgement for buffer head removing while doing checkpoint
2023-08-11 11:53:43 +02:00
jffs2
jffs2: reduce stack usage in jffs2_build_xattr_subsystem()
2023-07-27 08:37:25 +02:00
jfs
FS: JFS: Check for read-only mounted filesystem in txBegin
2023-08-30 16:27:10 +02:00
kernfs
new helper: lookup_positive_unlocked()
2023-09-23 10:59:40 +02:00
lockd
minix
minix: fix bug when opening a file with O_DIRECT
2022-04-15 14:18:35 +02:00
nfs
NFSv4: Fix dropped lock for racing OPEN and delegation return
2023-08-30 16:27:24 +02:00
nfs_common
nfsd
new helper: lookup_positive_unlocked()
2023-09-23 10:59:40 +02:00
nilfs2
nilfs2: fix WARNING in mark_buffer_dirty due to discarded buffer reuse
2023-09-23 10:59:37 +02:00
nls
fs/nls: make load_nls() take a const parameter
2023-09-23 10:59:38 +02:00
notify
fanotify: disallow mount/sb marks on kernel internal pseudo fs
2023-07-27 08:37:26 +02:00
ntfs
ntfs: check overflow when iterating ATTR_RECORDs
2022-11-25 17:42:22 +01:00
ocfs2
fs: ocfs2: namei: check return value of ocfs2_add_entry()
2023-09-23 10:59:42 +02:00
omfs
treewide: Remove uninitialized_var() usage
2023-06-09 10:29:01 +02:00
openpromfs
orangefs
orangefs: Fix kmemleak in orangefs_{kernel,client}_debug_init()
2023-01-18 11:41:39 +01:00
overlayfs
new helper: lookup_positive_unlocked()
2023-09-23 10:59:40 +02:00
proc
mm: hugetlb: proc: check for hugetlb shared PMD in /proc/PID/smaps
2023-02-22 12:50:28 +01:00
pstore
pstore/ram: Add check for kstrdup
2023-07-27 08:37:06 +02:00
qnx4
qnx6
quota
quota: fix dqput() to follow the guarantees dquot_srcu should provide
2023-09-23 10:59:43 +02:00
ramfs
reiserfs
reiserfs: Check the return value from __getblk()
2023-09-23 10:59:40 +02:00
romfs
squashfs
revert "squashfs: harden sanity check in squashfs_read_xattr_id_table"
2023-02-22 12:50:39 +01:00
sysfs
sysv
fs/sysv: Null check to prevent null-ptr-deref bug
2023-08-11 11:53:59 +02:00
tracefs
tracefs: Only clobber mode/uid/gid on remount if asked
2022-09-20 12:28:00 +02:00
ubifs
treewide: Remove uninitialized_var() usage
2023-06-09 10:29:01 +02:00
udf
udf: Handle error when adding extent to a file
2023-09-23 10:59:40 +02:00
ufs
unicode
verity
fsverity: don't drop pagecache at end of FS_IOC_ENABLE_VERITY
2023-04-05 11:16:42 +02:00
xfs
xfs: verify buffer contents when we skip log replay
2023-06-28 10:18:42 +02:00
aio.c
aio: fix mremap after fork null-deref
2023-02-22 12:50:35 +01:00
anon_inodes.c
attr.c
vfs: Check the truncate maximum size in inode_newsize_ok()
2022-08-25 11:17:21 +02:00
bad_inode.c
binfmt_aout.c
binfmt: Move install_exec_creds after setup_new_exec to match binfmt_elf
2023-01-18 11:41:46 +01:00
binfmt_elf.c
binfmt_elf_fdpic.c
binfmt: Fix error return code in load_elf_fdpic_binary()
2023-01-18 11:41:46 +01:00
binfmt_em86.c
binfmt_flat.c
binfmt: Move install_exec_creds after setup_new_exec to match binfmt_elf
2023-01-18 11:41:46 +01:00
binfmt_misc.c
binfmt_misc: fix shift-out-of-bounds in check_special_flags
2023-01-18 11:41:33 +01:00
binfmt_script.c
block_dev.c
buffer.c
mm: fs: initialize fsdata passed to write_begin/write_end interface
2022-11-25 17:42:22 +01:00
char_dev.c
chardev: fix error handling in cdev_device_add()
2023-01-18 11:41:25 +01:00
compat.c
compat_binfmt_elf.c
compat_ioctl.c
compat_ioctl: remove /dev/random commands
2022-06-22 14:11:03 +02:00
coredump.c
d_path.c
dax.c
dax: fix cache flush on PMD-mapped pages
2022-06-14 18:11:41 +02:00
dcache.c
dcookies.c
direct-io.c
drop_caches.c
eventfd.c
eventfd: prevent underflow for eventfd semaphores
2023-09-23 10:59:40 +02:00
eventpoll.c
epoll: ep_autoremove_wake_function should use list_del_init_careful
2023-06-28 10:18:35 +02:00
exec.c
exec: Force single empty string when argv is empty
2022-06-06 08:33:50 +02:00
fcntl.c
fhandle.c
file.c
fs: prevent out-of-bounds array speculation when closing a file descriptor
2023-03-17 08:32:47 +01:00
file_table.c
SUNRPC: Ensure we flush any closed sockets before xs_xprt_free()
2022-05-25 09:14:34 +02:00
filesystems.c
fs-writeback.c
writeback: fix call of incorrect macro
2023-05-17 11:35:58 +02:00
fs_context.c
fs: avoid empty option when generating legacy mount string
2023-07-27 08:37:25 +02:00
fs_parser.c
fs_pin.c
fs_struct.c
fs_types.c
fsopen.c
inode.c
fs: Establish locking order for unrelated directories
2023-07-27 08:37:26 +02:00
internal.h
fs: Establish locking order for unrelated directories
2023-07-27 08:37:26 +02:00
io_uring.c
io_uring: have io_kill_timeout() honor the request references
2023-06-05 08:17:32 +02:00
ioctl.c
Kconfig
Kconfig.binfmt
libfs.c
libfs: add DEFINE_SIMPLE_ATTRIBUTE_SIGNED for signed value
2023-01-18 11:40:55 +01:00
locks.c
Makefile
mbcache.c
mbcache: Avoid nesting of cache->c_list_lock under bit locks
2023-01-18 11:41:59 +01:00
mount.h
mpage.c
namei.c
fs: Fix error checking for d_hash_and_lookup()
2023-09-23 10:59:40 +02:00
namespace.c
no-block.c
nsfs.c
open.c
pipe.c
pnode.c
pnode: terminate at peers of source
2023-01-18 11:41:44 +01:00
pnode.h
posix_acl.c
proc_namespace.c
read_write.c
readdir.c
select.c
select: Fix indefinitely sleeping task in poll_schedule_timeout()
2022-01-29 10:25:11 +01:00
seq_file.c
signalfd.c
io_uring: disable polling pollfree files
2022-09-05 10:27:47 +02:00
splice.c
Revert "fs: check FMODE_LSEEK to control internal pipe splicing"
2022-10-17 17:24:32 +02:00
stack.c
stat.c
stat: fix inconsistency between struct stat and struct compat_stat
2022-04-27 13:50:48 +02:00
statfs.c
statfs: enforce statfs[64] structure initialization
2023-05-30 12:44:07 +01:00
super.c
fs: Protect reconfiguration of sb read-write from racing writes
2023-08-11 11:53:59 +02:00
sync.c
timerfd.c
userfaultfd.c
userfaultfd: open userfaultfds with O_RDONLY
2022-10-26 13:22:21 +02:00
utimes.c
xattr.c
fs: don't audit the capability check in simple_xattr_list()
2023-01-18 11:40:53 +01:00