Re: [f2fs-dev] [PATCH] f2fs: fix to avoid UAF in f2fs_write_end_io()
From: Guenter Roeck
Date: Sun Mar 01 2026 - 20:32:27 EST
Hi,
On Wed, Jan 07, 2026 at 07:22:18PM +0800, Chao Yu wrote:
> As syzbot reported an use-after-free issue in f2fs_write_end_io().
>
> It is caused by below race condition:
>
> loop device umount
> - worker_thread
> - loop_process_work
> - do_req_filebacked
> - lo_rw_aio
> - lo_rw_aio_complete
> - blk_mq_end_request
> - blk_update_request
> - f2fs_write_end_io
> - dec_page_count
> - folio_end_writeback
> - kill_f2fs_super
> - kill_block_super
> - f2fs_put_super
> : free(sbi)
> : get_pages(, F2FS_WB_CP_DATA)
> accessed sbi which is freed
>
> In kill_f2fs_super(), we will drop all page caches of f2fs inodes before
> call free(sbi), it guarantee that all folios should end its writeback, so
> it should be safe to access sbi before last folio_end_writeback().
>
> Let's relocate ckpt thread wakeup flow before folio_end_writeback() to
> resolve this issue.
>
> Cc: stable@xxxxxxxxxx
> Fixes: e234088758fc ("f2fs: avoid wait if IO end up when do_checkpoint for better performance")
> Reported-by: syzbot+b4444e3c972a7a124187@xxxxxxxxxxxxxxxxxxxxxxxxx
> Closes: https://syzkaller.appspot.com/bug?extid=b4444e3c972a7a124187
> Signed-off-by: Chao Yu <chao@xxxxxxxxxx>
> ---
> fs/f2fs/data.c | 12 +++++++++---
> 1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index c30e69392a62..8550c964b71c 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -356,14 +356,20 @@ static void f2fs_write_end_io(struct bio *bio)
> folio->index != nid_of_node(folio));
>
>From the code:
#ifdef CONFIG_F2FS_FS_COMPRESSION
if (f2fs_is_compressed_page(folio)) {
f2fs_compress_write_end_io(bio, folio);
continue;
}
#endif
...
> dec_page_count(sbi, type);
> +
> + /*
> + * we should access sbi before folio_end_writeback() to
> + * avoid racing w/ kill_f2fs_super()
> + */
> + if (type == F2FS_WB_CP_DATA && !get_pages(sbi, type) &&
> + wq_has_sleeper(&sbi->cp_wait))
> + wake_up(&sbi->cp_wait);
> +
As the above snippet shows, the wakeup logic is now skipped for compressed
pages, and may be skipped entirely if the last page is a compressed page.
Also, givven that f2fs_compress_write_end_io() is kind of similar to the
code below for compressed pages, does that mean that there is a similar
potential UAF vulnerability for compressed pages in that function ?
Thanks,
Guenter
> if (f2fs_in_warm_node_list(sbi, folio))
> f2fs_del_fsync_node_entry(sbi, folio);
> folio_clear_f2fs_gcing(folio);
> folio_end_writeback(folio);
> }
> - if (!get_pages(sbi, F2FS_WB_CP_DATA) &&
> - wq_has_sleeper(&sbi->cp_wait))
> - wake_up(&sbi->cp_wait);
>
> bio_put(bio);
> }