mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
skd: Avoid that module unloading triggers a use-after-free
commit 7277cc67b3 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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
f05dafbd77
commit
0bcaf5178f
@@ -4679,15 +4679,16 @@ static void skd_free_disk(struct skd_device *skdev)
|
||||
{
|
||||
struct gendisk *disk = skdev->disk;
|
||||
|
||||
if (disk != NULL) {
|
||||
struct request_queue *q = disk->queue;
|
||||
if (disk && (disk->flags & GENHD_FL_UP))
|
||||
del_gendisk(disk);
|
||||
|
||||
if (disk->flags & GENHD_FL_UP)
|
||||
del_gendisk(disk);
|
||||
if (q)
|
||||
blk_cleanup_queue(q);
|
||||
put_disk(disk);
|
||||
if (skdev->queue) {
|
||||
blk_cleanup_queue(skdev->queue);
|
||||
skdev->queue = NULL;
|
||||
disk->queue = NULL;
|
||||
}
|
||||
|
||||
put_disk(disk);
|
||||
skdev->disk = NULL;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user