• Tejun Heo's avatar
    writeback, cgroup: fix premature wb_put() in locked_inode_to_wb_and_lock_list() · d78ddcfb
    Tejun Heo authored
    commit 614a4e37 upstream.
    
    locked_inode_to_wb_and_lock_list() wb_get()'s the wb associated with
    the target inode, unlocks inode, locks the wb's list_lock and verifies
    that the inode is still associated with the wb.  To prevent the wb
    going away between dropping inode lock and acquiring list_lock, the wb
    is pinned while inode lock is held.  The wb reference is put right
    after acquiring list_lock citing that the wb won't be dereferenced
    anymore.
    
    This isn't true.  If the inode is still associated with the wb, the
    inode has reference and it's safe to return the wb; however, if inode
    has been switched, the wb still needs to be unlocked which is a
    dereference and can lead to use-after-free if it it races with wb
    destruction.
    
    Fix it by putting the reference after releasing list_lock.
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Fixes: 87e1d789 ("writeback: implement [locked_]inode_to_wb_and_lock_list()")
    Tested-by: default avatarTahsin Erdogan <tahsin@google.com>
    Signed-off-by: default avatarJens Axboe <axboe@fb.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    d78ddcfb
fs-writeback.c 68.4 KB