Re: [PATCH v4] block: genhd: don't call probe function with major_names_lock held
From: Greg KH <gregkh@linuxfoundation.org>
Date: 2021-08-18 13:28:20
On Wed, Aug 18, 2021 at 08:07:32PM +0900, Tetsuo Handa wrote:
syzbot is reporting circular locking problem at __loop_clr_fd() [1], for
commit a160c6159d4a0cf8 ("block: add an optional probe callback to
major_names") is calling the module's probe function with major_names_lock
held.
When copying content of /proc/devices to another file via sendfile(),
sb_writers#$N => &p->lock => major_names_lock
dependency is recorded.
When loop_process_work() from WQ context performs a write request,
(wq_completion)loop$M => (work_completion)&lo->rootcg_work =>
sb_writers#$N
dependency is recorded.
When flush_workqueue() from drain_workqueue() from destroy_workqueue()
from __loop_clr_fd() from blkdev_put() from blkdev_close() from __fput()
is called,
&disk->open_mutex => &lo->lo_mutex => (wq_completion)loop$M
dependency is recorded.
When loop_control_remove() from loop_control_ioctl(LOOP_CTL_REMOVE) is
called,
loop_ctl_mutex => &lo->lo_mutex
dependency is recorded.
As a result, lockdep thinks that there is
loop_ctl_mutex => &lo->lo_mutex => (wq_completion)loop$M =>
(work_completion)&lo->rootcg_work => sb_writers#$N => &p->lock =>
major_names_lock
dependency chain.
Then, if loop_add() from loop_probe() from blk_request_module() from
blkdev_get_no_open() from blkdev_get_by_dev() from blkdev_open() from
do_dentry_open() from path_openat() from do_filp_open() is called,
major_names_lock => loop_ctl_mutex
dependency is appended to the dependency chain.
There would be two approaches for breaking this circular dependency.
One is to kill loop_ctl_mutex => &lo->lo_mutex chain. The other is to
kill major_names_lock => loop_ctl_mutex chain. This patch implements
the latter, due to the following reasons.
(1) sb_writers#$N => &p->lock => major_names_lock chain is unavoidable
(2) this patch can also fix similar problem in other modules [2] which
is caused by calling the probe function with major_names_lock held
(3) I believe that this patch is principally safer than e.g.
commit bd5c39edad535d9f ("loop: reduce loop_ctl_mutex coverage in
loop_exit") which waits until the probe function finishes using
global mutex in order to fix deadlock reproducible by sleep
injection [3]
This patch adds THIS_MODULE parameter to __register_blkdev() as with
usb_register(), and drops major_names_lock before calling probe function
by holding a reference to that module which contains that probe function.
Since cdev uses register_chrdev() and __register_chrdev(), bdev should be
able to preserve register_blkdev() and __register_blkdev() naming scheme.Note, the cdev api is anything but good, so should not be used as an excuse for anything. Don't copy it unless you have a very good reason. Also, what changed in this version? I see no patch history here :( thanks, greg k-h