]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
fuse: launder page should wait for page writeback
authorMiklos Szeredi <mszeredi@redhat.com>
Wed, 11 Nov 2020 16:22:31 +0000 (17:22 +0100)
committerMiklos Szeredi <mszeredi@redhat.com>
Wed, 11 Nov 2020 16:22:31 +0000 (17:22 +0100)
Qian Cai reports that the WARNING in tree_insert() can be triggered by a
fuzzer with the following call chain:

invalidate_inode_pages2_range()
   fuse_launder_page()
      fuse_writepage_locked()
         tree_insert()

The reason is that another write for the same page is already queued.

The simplest fix is to wait until the pending write is completed and only
after that queue the new write.

Since this case is very rare, the additional wait should not be a problem.

Reported-by: Qian Cai <cai@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/file.c

index c03034e8c1529c53cd11671d6e6dfe3ac4ba6ce6..41b1e14f38208a4df96e7502972d9c2e1b76c28f 100644 (file)
@@ -2281,6 +2281,9 @@ static int fuse_launder_page(struct page *page)
        int err = 0;
        if (clear_page_dirty_for_io(page)) {
                struct inode *inode = page->mapping->host;
+
+               /* Serialize with pending writeback for the same page */
+               fuse_wait_on_page_writeback(inode, page->index);
                err = fuse_writepage_locked(page);
                if (!err)
                        fuse_wait_on_page_writeback(inode, page->index);