[PATCH v4 14/18] f2fs: wait for folio writeback before ffs_detach_free

From: Nanzhe Zhao

Date: Tue Oct 13 2026 - 09:19:31 EST


From: Nanzhe Zhao <zhaonanzhe@xxxxxxxxxx>

truncate_inode_pages_range() can invalidate a large folio that is still
under writeback, which can result in the following use-after-free:

CPU0 (writeback) CPU1 (truncate)
---- ----
f2fs_write_cache_folios()
folio_start_writeback(folio)
/* submit bios */

retry_out:
folio_unlock(folio)
/* all bios submitted; folio lock released */

truncate_inode_pages_range()
find_lock_entries() /* locks the folio */
truncate_cleanup_folio(folio)
folio_invalidate(folio, 0, folio_size(folio))
-> f2fs_invalidate_folio(folio, 0,
folio_size(folio))

f2fs_write_end_bio(bio)
ffs = folio->private ffs_detach_free(folio)
folio_detach_private(folio)
kfree(ffs)
atomic_sub_and_test(nr_pages,
&ffs->write_pages_pending) <-- use-after-free

Wait for folio writeback in invalidate_folio, then we can free the
folio state without any other remaining user.

Reported-by: kernel test robot <yi1.lai@xxxxxxxxx>
Closes: https://lore.kernel.org/oe-lkp/202610081027.b13dcf10-lkp@xxxxxxxxx
Signed-off-by: Nanzhe Zhao <zhaonanzhe@xxxxxxxxxx>
---
fs/f2fs/data.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 61fe4a0c5..433d8f2b0 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -5427,6 +5427,14 @@ void f2fs_invalidate_folio(struct folio *folio, size_t offset, size_t length)
}

if (f2fs_folio_has_ffs(folio)) {
+ /*
+ * The folio may still be under writeback with bios in
+ * completion that need to access f2fs_folio_state. Wait
+ * for the writeback to complete before freeing the state,
+ * otherwise it will result in use-after-free.
+ */
+ folio_wait_writeback(folio);
+
f2fs_ffs_clear_subrange_dirty_and_test(folio, 0,
folio_size(folio));
} else if (folio_test_dirty(folio)) {
--
2.43.0