• Zhang Yi's avatar
    ext4: fix an use-after-free issue about data=journal writeback mode · 5c48a7df
    Zhang Yi authored
    Our syzkaller report an use-after-free issue that accessing the freed
    buffer_head on the writeback page in __ext4_journalled_writepage(). The
    problem is that if there was a truncate racing with the data=journalled
    writeback procedure, the writeback length could become zero and
    bget_one() refuse to get buffer_head's refcount, then the truncate
    procedure release buffer once we drop page lock, finally, the last
    ext4_walk_page_buffers() trigger the use-after-free problem.
    
    sync                               truncate
    ext4_sync_file()
     file_write_and_wait_range()
                                       ext4_setattr(0)
                                        inode->i_size = 0
      ext4_writepage()
       len = 0
       __ext4_journalled_writepage()
        page_bufs = page_buffers(page)
        ext4_walk_page_buffers(bget_one) <- does not get refcount
                                        do_invalidatepage()
                                          free_buffer_head()
        ext4_walk_page_buffers(page_bufs) <- trigger use-after-free
    
    After commit bdf96838 ("ext4: fix race between truncate and
    __ext4_journalled_writepage()"), we have already handled the racing
    case, so the bget_one() and bput_one() are not needed. So this patch
    simply remove these hunk, and recheck the i_size to make it safe.
    
    Fixes: bdf96838 ("ext4: fix race between truncate and __ext4_journalled_writepage()")
    Signed-off-by: default avatarZhang Yi <yi.zhang@huawei.com>
    Cc: stable@vger.kernel.org
    Link: https://lore.kernel.org/r/20211225090937.712867-1-yi.zhang@huawei.comSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
    5c48a7df
inode.c 177 KB