CVE-2022-48920 Information
Description
In the Linux kernel the following vulnerability has been resolved:
btrfs: get rid of warning on transaction commit when using flushoncommit
When using the flushoncommit mount option during almost every transaction commit we trigger a warning from __writeback_inodes_sb_nr():
$ cat fs/fs-writeback.c: (…) static void __writeback_inodes_sb_nr(struct super_block sb …
(...)
WARN_ON(!rwsem_is_locked(&sb->s_umount));
(...)
(…)
The trace produced in dmesg looks like the following:
[947.473890] WARNING: CPU: 5 PID: 930 at fs/fs-writeback.c:2610 __writeback_inodes_sb_nr+0x7e/0xb3
[947.481623] Modules linked in: nfsd nls_cp437 cifs asn1_decoder cifs_arc4 fscache cifs_md4 ipmi_ssif
[947.489571] CPU: 5 PID: 930 Comm: btrfs-transacti Not tainted 95.16.3-srb-asrock-00001-g36437ad63879 186
[947.497969] RIP: 0010:__writeback_inodes_sb_nr+0x7e/0xb3
[947.502097] Code: 24 10 4c 89 44 24 18 c6 (…)
[947.519760] RSP: 0018:ffffc90000777e10 EFLAGS: 00010246
[947.523818] RAX: 0000000000000000 RBX: 0000000000963300 RCX: 0000000000000000
[947.529765] RDX: 0000000000000000 RSI: 000000000000fa51 RDI: ffffc90000777e50
[947.535740] RBP: ffff888101628a90 R08: ffff888100955800 R09: ffff888100956000
[947.541701] R10: 0000000000000002 R11: 0000000000000001 R12: ffff888100963488
[947.547645] R13: ffff888100963000 R14: ffff888112fb7200 R15: ffff888100963460
[947.553621] FS: 0000000000000000(0000) GS:ffff88841fd40000(0000) knlGS:0000000000000000
[947.560537] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[947.565122] CR2: 0000000008be50c4 CR3: 000000000220c000 CR4: 00000000001006e0
[947.571072] Call Trace:
[947.572354]
This is because we started using writeback_inodes_sb() to flush delalloc when committing a transaction (when using -o flushoncommit) in order to avoid deadlocks with filesystem freeze operations. This change was made by commit ce8ea7cc6eb313 (trfs: don’t call btrfs_start_delalloc_roots in flushoncommit). After that change we started producing that warning and every now and then a user reports this since the warning happens too often it spams dmesg/syslog and a user is unsure if this reflects any problem that might compromise the filesystem’s reliability.
We can not just lock the sb->s_umount semaphore before calling writeback_inodes_sb() because that would at least deadlock with filesystem freezing since at fs/super.c:freeze_super() sync_filesystem() is called while we are holding that semaphore in write mode and that can trigger a transaction commit resulting in a deadlock. It would also trigger the same type of deadlock in the unmount path. Possibly it could also introduce some other locking dependencies that lockdep would report.
To fix this call try_to_writeback_inodes_sb() instead of writeback_inodes_sb() because that will try to read lock sb->s_umount and then will only call writeback_inodes_sb() if it was able to lock it. This is fine because the cases where it can’t read lock sb->s_umount are during a filesystem unmount or during a filesystem freeze - in those cases sb->s_umount is write locked and sync_filesystem() is called which calls writeback_inodes_sb(). In other words in all cases where we can’t take a read lock on sb->s_umount writeback is already being triggered elsewhere.
An alternative would be to call btrfs_start_delalloc_roots() with a number of pages different from LONG_MAX for example matching the number of delalloc bytes we currently have in
truncated—
Reference
https://git.kernel.org/stable/c/850a77c999b81dd2724efd2684068d6f90db8c16 https://git.kernel.org/stable/c/e4d044dbffcd570351f21c747fc77ff90aed7f2e https://git.kernel.org/stable/c/a0f0cf8341e34e5d2265bfd3a7ad68342da1e2aa
Share on: