Syzkaller reports warning in ext4_set_page_dirty() in 5.10 and 5.15 stable releases. It happens because invalidate_inode_page() frees pages that are needed for the system. To fix this we need to add additional checks to the function. page_mapped() checks if a page exists in the page tables, but this is not enough. The page can be used in other places: https://elixir.bootlin.com/linux/v6.8-rc1/source/include/linux/page_ref.h#L7...
Kernel outputs an error line related to direct I/O: https://syzkaller.appspot.com/text?tag=CrashLog&x=14ab52dac80000
The problem can be fixed in 5.10 and 5.15 stable releases by the following patch.
The patch replaces page_mapped() call with check that finds additional references to the page excluding page cache and filesystem private data. If additional references exist, the page cannot be freed.
This version does not include the first patch from the first version. The problem can be fixed without it.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Link: https://syzkaller.appspot.com/bug?extid=02f21431b65c214aa1d6
Matthew Wilcox (Oracle) (1): mm/truncate: Replace page_mapped() call in invalidate_inode_page()
mm/truncate.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)