]> git.kernelconcepts.de Git - karo-tx-linux.git/commit
writeback, cgroup: fix premature wb_put() in locked_inode_to_wb_and_lock_list()
authorTejun Heo <tj@kernel.org>
Fri, 18 Mar 2016 17:50:03 +0000 (13:50 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 Apr 2016 16:09:04 +0000 (09:09 -0700)
commitd78ddcfbe7ab8c5f4ff0b8f20b2bbda710fc0e91
treef34f30667c471e0c55dabb324ee55045824af802
parentb05e5a587ddc11255de76657e6b4b0e960783cc3
writeback, cgroup: fix premature wb_put() in locked_inode_to_wb_and_lock_list()

commit 614a4e3773148a31f58dc174bbf578ceb63510c2 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: Tejun Heo <tj@kernel.org>
Fixes: 87e1d789bf55 ("writeback: implement [locked_]inode_to_wb_and_lock_list()")
Tested-by: Tahsin Erdogan <tahsin@google.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/fs-writeback.c