[lvc-project] [PATCH] f2fs: Add a flush_work() call before destroying raw_super
Andrey Tsygunka
aitsygunka at yandex.ru
Wed Apr 29 13:32:06 MSK 2026
KASAN reports a use-after-free in f2fs_record_stop_reason(), called
from f2fs_record_error_work() during the execution of s_error_work.
The error occurs when attempting to access sbi->raw_super after it
was freed in f2fs_fill_super().
The reason for this error is that some superblock initialization error
handling in f2fs_fill_super() frees raw_super while s_error_work has
not yet completed execution, leading to a race condition
and use-after-free.
To prevent this race condition, add flush_work(&sbi->s_error_work)
before kfree(raw_super).
Reported by syzkaller:
BUG: KASAN: slab-use-after-free in f2fs_record_stop_reason fs/f2fs/super.c:4151 [inline]
BUG: KASAN: slab-use-after-free in f2fs_record_error_work+0x11e/0x210 fs/f2fs/super.c:4256
Write of size 16 at addr ffff888026d52aea by task kworker/1:4/862
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Workqueue:events f2fs_record_error_work
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0xcf/0x130 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:377 [inline]
print_report+0xc1/0x600 mm/kasan/report.c:481
kasan_report+0xbd/0xf0 mm/kasan/report.c:594
check_region_inline mm/kasan/generic.c:183 [inline]
kasan_check_range+0xf4/0x1a0 mm/kasan/generic.c:189
__asan_memcpy+0x3d/0x60 mm/kasan/shadow.c:106
f2fs_record_stop_reason fs/f2fs/super.c:4151 [inline]
f2fs_record_error_work+0x11e/0x210 fs/f2fs/super.c:4256
process_one_work+0x91e/0x1a60 kernel/workqueue.c:3252
process_scheduled_works kernel/workqueue.c:3333 [inline]
worker_thread+0x677/0xe80 kernel/workqueue.c:3414
kthread+0x333/0x440 kernel/kthread.c:389
ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:152
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
</TASK>
Allocated by task 5537:
kasan_save_stack+0x24/0x50 mm/kasan/common.c:48
kasan_save_track+0x14/0x30 mm/kasan/common.c:69
poison_kmalloc_redzone mm/kasan/common.c:378 [inline]
__kasan_kmalloc+0x7f/0x90 mm/kasan/common.c:395
kmalloc_noprof include/linux/slab.h:878 [inline]
kzalloc_noprof include/linux/slab.h:1014 [inline]
read_raw_super_block fs/f2fs/super.c:4047 [inline]
f2fs_fill_super+0x3a9/0x8ab0 fs/f2fs/super.c:4517
mount_bdev+0x1e9/0x2e0 fs/super.c:1693
legacy_get_tree+0x10c/0x220 fs/fs_context.c:662
vfs_get_tree+0x94/0x380 fs/super.c:1814
do_new_mount fs/namespace.c:3564 [inline]
path_mount+0x6b2/0x1f90 fs/namespace.c:3891
do_mount fs/namespace.c:3904 [inline]
__do_sys_mount fs/namespace.c:4114 [inline]
__se_sys_mount fs/namespace.c:4091 [inline]
__x64_sys_mount+0x284/0x310 fs/namespace.c:4091
do_syscall_x64 arch/x86/entry/common.c:47 [inline]
do_syscall_64+0x68/0x140 arch/x86/entry/common.c:78
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Freed by task 5537:
kasan_save_stack+0x24/0x50 mm/kasan/common.c:48
kasan_save_track+0x14/0x30 mm/kasan/common.c:69
kasan_save_free_info+0x3b/0x60 mm/kasan/generic.c:579
poison_slab_object mm/kasan/common.c:248 [inline]
__kasan_slab_free+0x38/0x50 mm/kasan/common.c:265
kasan_slab_free include/linux/kasan.h:234 [inline]
slab_free_hook mm/slub.c:2393 [inline]
slab_free mm/slub.c:4651 [inline]
kfree+0x13d/0x4a0 mm/slub.c:4803
f2fs_fill_super+0x437b/0x8ab0 fs/f2fs/super.c:4957
mount_bdev+0x1e9/0x2e0 fs/super.c:1693
legacy_get_tree+0x10c/0x220 fs/fs_context.c:662
vfs_get_tree+0x94/0x380 fs/super.c:1814
do_new_mount fs/namespace.c:3564 [inline]
path_mount+0x6b2/0x1f90 fs/namespace.c:3891
do_mount fs/namespace.c:3904 [inline]
__do_sys_mount fs/namespace.c:4114 [inline]
__se_sys_mount fs/namespace.c:4091 [inline]
__x64_sys_mount+0x284/0x310 fs/namespace.c:4091
do_syscall_x64 arch/x86/entry/common.c:47 [inline]
do_syscall_64+0x68/0x140 arch/x86/entry/common.c:78
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Fixes: b62e71be2110 ("f2fs: support errors=remount-ro|continue|panic mountoption")
Signed-off-by: Andrey Tsygunka <aitsygunka at yandex.ru>
---
fs/f2fs/super.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index ccf806b676f5..e9fe57e4aef2 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -5449,6 +5449,8 @@ static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc)
/* no need to free dummy_enc_policy, we just keep it in ctx when failed */
swap(F2FS_CTX_INFO(ctx).dummy_enc_policy, F2FS_OPTION(sbi).dummy_enc_policy);
free_sb_buf:
+ /* flush s_error_work before raw_super destroy */
+ flush_work(&sbi->s_error_work);
kfree(raw_super);
free_sbi:
#ifdef CONFIG_DEBUG_LOCK_ALLOC
--
2.25.1
More information about the lvc-project
mailing list