syzbot report null-ptr-deref Write in f2fs_stop_gc_thread, because shutdown and remount can cause multi-path entry into f2fs_stop_gc_thread, resulting in incorrect access to f2fs_gc_task before it is properly initialized.
Reported-and-tested-by: syzbot+1a8e2b31f2ac9bd3d...@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=1a8e2b31f2ac9bd3d148 Signed-off-by: Edward Adam Davis <eada...@qq.com> --- fs/f2fs/gc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 6066c6eecf41..a624e8271fbc 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -27,6 +27,7 @@ static struct kmem_cache *victim_entry_slab; static unsigned int count_bits(const unsigned long *addr, unsigned int offset, unsigned int len); +static DEFINE_MUTEX(gc_lock); static int gc_thread_func(void *data) { @@ -203,10 +204,13 @@ int f2fs_start_gc_thread(struct f2fs_sb_info *sbi) void f2fs_stop_gc_thread(struct f2fs_sb_info *sbi) { - struct f2fs_gc_kthread *gc_th = sbi->gc_thread; + struct f2fs_gc_kthread *gc_th; - if (!gc_th) + guard(mutex)(&gc_lock); + gc_th = sbi->gc_thread; + if (!gc_th || gc_th->f2fs_gc_task < PAGE_OFFSET) return; + kthread_stop(gc_th->f2fs_gc_task); wake_up_all(&gc_th->fggc_wq); kfree(gc_th); -- 2.43.0 _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel