Skip to content

Commit 0bcaf51

Browse files
KAGA-KOKOgregkh
authored andcommitted
skd: Avoid that module unloading triggers a use-after-free
commit 7277cc67b3916eed47558c64f9c9c0de00a35cda upstream. Since put_disk() triggers a disk_release() call and since that last function calls blk_put_queue() if disk->queue != NULL, clear the disk->queue pointer before calling put_disk(). This avoids that unloading the skd kernel module triggers the following use-after-free: WARNING: CPU: 8 PID: 297 at lib/refcount.c:128 refcount_sub_and_test+0x70/0x80 refcount_t: underflow; use-after-free. CPU: 8 PID: 297 Comm: kworker/8:1 Not tainted 4.11.10-300.fc26.x86_64 #1 Workqueue: events work_for_cpu_fn Call Trace: dump_stack+0x63/0x84 __warn+0xcb/0xf0 warn_slowpath_fmt+0x5a/0x80 refcount_sub_and_test+0x70/0x80 refcount_dec_and_test+0x11/0x20 kobject_put+0x1f/0x50 blk_put_queue+0x15/0x20 disk_release+0xae/0xf0 device_release+0x32/0x90 kobject_release+0x67/0x170 kobject_put+0x2b/0x50 put_disk+0x17/0x20 skd_destruct+0x5c/0x890 [skd] skd_pci_probe+0x124d/0x13a0 [skd] local_pci_probe+0x42/0xa0 work_for_cpu_fn+0x14/0x20 process_one_work+0x19e/0x470 worker_thread+0x1dc/0x4a0 kthread+0x125/0x140 ret_from_fork+0x25/0x30 Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Hannes Reinecke <hare@suse.de> Cc: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent f05dafb commit 0bcaf51

1 file changed

Lines changed: 8 additions & 7 deletions

File tree

drivers/block/skd_main.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4679,15 +4679,16 @@ static void skd_free_disk(struct skd_device *skdev)
46794679
{
46804680
struct gendisk *disk = skdev->disk;
46814681

4682-
if (disk != NULL) {
4683-
struct request_queue *q = disk->queue;
4682+
if (disk && (disk->flags & GENHD_FL_UP))
4683+
del_gendisk(disk);
46844684

4685-
if (disk->flags & GENHD_FL_UP)
4686-
del_gendisk(disk);
4687-
if (q)
4688-
blk_cleanup_queue(q);
4689-
put_disk(disk);
4685+
if (skdev->queue) {
4686+
blk_cleanup_queue(skdev->queue);
4687+
skdev->queue = NULL;
4688+
disk->queue = NULL;
46904689
}
4690+
4691+
put_disk(disk);
46914692
skdev->disk = NULL;
46924693
}
46934694

0 commit comments

Comments
 (0)