scsi: Fix use-after-free
This patch fixes one use-after-free report[1] by KASAN.
In __scsi_scan_target(), when a type 31 device is probed,
SCSI_SCAN_TARGET_PRESENT is returned and the target will be scanned
again.
Inside the following scsi_report_lun_scan(), one new scsi_device
instance is allocated, and scsi_probe_and_add_lun() is called again to
probe the target and still see type 31 device, finally
__scsi_remove_device() is called to remove & free the device at the end
of scsi_probe_and_add_lun(), so cause use-after-free in
scsi_report_lun_scan().
And the following SCSI log can be observed:
scsi 0:0:2:0: scsi scan: INQUIRY pass 1 length 36
scsi 0:0:2:0: scsi scan: INQUIRY successful with code 0x0
scsi 0:0:2:0: scsi scan: peripheral device type of 31, no device added
scsi 0:0:2:0: scsi scan: Sending REPORT LUNS to (try 0)
scsi 0:0:2:0: scsi scan: REPORT LUNS successful (try 0) result 0x0
scsi 0:0:2:0: scsi scan: REPORT LUN scan
scsi 0:0:2:0: scsi scan: INQUIRY pass 1 length 36
scsi 0:0:2:0: scsi scan: INQUIRY successful with code 0x0
scsi 0:0:2:0: scsi scan: peripheral device type of 31, no device added
BUG: KASAN: use-after-free in __scsi_scan_target+0xbf8/0xe40 at addr
ffff88007b44a104
This patch fixes the issue by moving the putting reference at
the end of scsi_report_lun_scan().
[1] KASAN report
==================================================================
[ 3.274597] PM: Adding info for serio:serio1
[ 3.275127] BUG: KASAN: use-after-free in __scsi_scan_target+0xd87/0xdf0 at addr
ffff880254d8c304
[ 3.275653] Read of size 4 by task kworker/u10:0/27
[ 3.275903] CPU: 3 PID: 27 Comm: kworker/u10:0 Not tainted 4.8.0 #2121
[ 3.276258] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[ 3.276797] Workqueue: events_unbound async_run_entry_fn
[ 3.277083]
ffff880254d8c380 ffff880259a37870 ffffffff94bbc6c1 ffff880078402d80
[ 3.277532]
ffff880254d8bb80 ffff880259a37898 ffffffff9459fec1 ffff880259a37930
[ 3.277989]
ffff880254d8bb80 ffff880078402d80 ffff880259a37920 ffffffff945a0165
[ 3.278436] Call Trace:
[ 3.278528] [<
ffffffff94bbc6c1>] dump_stack+0x65/0x84
[ 3.278797] [<
ffffffff9459fec1>] kasan_object_err+0x21/0x70
[ 3.279063] device: 'psaux': device_add
[ 3.279616] [<
ffffffff945a0165>] kasan_report_error+0x205/0x500
[ 3.279651] PM: Adding info for No Bus:psaux
[ 3.280202] [<
ffffffff944ecd22>] ? kfree_const+0x22/0x30
[ 3.280486] [<
ffffffff94bc2dc9>] ? kobject_release+0x119/0x370
[ 3.280805] [<
ffffffff945a0543>] __asan_report_load4_noabort+0x43/0x50
[ 3.281170] [<
ffffffff9507e1f7>] ? __scsi_scan_target+0xd87/0xdf0
[ 3.281506] [<
ffffffff9507e1f7>] __scsi_scan_target+0xd87/0xdf0
[ 3.281848] [<
ffffffff9507d470>] ? scsi_add_device+0x30/0x30
[ 3.282156] [<
ffffffff94f7f660>] ? pm_runtime_autosuspend_expiration+0x60/0x60
[ 3.282570] [<
ffffffff956ddb07>] ? _raw_spin_lock+0x17/0x40
[ 3.282880] [<
ffffffff9507e505>] scsi_scan_channel+0x105/0x160
[ 3.283200] [<
ffffffff9507e8a2>] scsi_scan_host_selected+0x212/0x2f0
[ 3.283563] [<
ffffffff9507eb3c>] do_scsi_scan_host+0x1bc/0x250
[ 3.283882] [<
ffffffff9507efc1>] do_scan_async+0x41/0x450
[ 3.284173] [<
ffffffff941c1fee>] async_run_entry_fn+0xfe/0x610
[ 3.284492] [<
ffffffff941a8954>] ? pwq_dec_nr_in_flight+0x124/0x2a0
[ 3.284876] [<
ffffffff941d1770>] ? preempt_count_add+0x130/0x160
[ 3.285207] [<
ffffffff941a9a84>] process_one_work+0x544/0x12d0
[ 3.285526] [<
ffffffff941aa8e9>] worker_thread+0xd9/0x12f0
[ 3.285844] [<
ffffffff941aa810>] ? process_one_work+0x12d0/0x12d0
[ 3.286182] [<
ffffffff941bb365>] kthread+0x1c5/0x260
[ 3.286443] [<
ffffffff940855cd>] ? __switch_to+0x88d/0x1430
[ 3.286745] [<
ffffffff941bb1a0>] ? kthread_worker_fn+0x5a0/0x5a0
[ 3.287085] [<
ffffffff956dde9f>] ret_from_fork+0x1f/0x40
[ 3.287368] [<
ffffffff941bb1a0>] ? kthread_worker_fn+0x5a0/0x5a0
[ 3.287697] Object at
ffff880254d8bb80, in cache kmalloc-2048 size: 2048
[ 3.288064] Allocated:
[ 3.288147] PID = 27
[ 3.288218] [<
ffffffff940b27ab>] save_stack_trace+0x2b/0x50
[ 3.288531] [<
ffffffff9459f246>] save_stack+0x46/0xd0
[ 3.288806] [<
ffffffff9459f4bd>] kasan_kmalloc+0xad/0xe0
[ 3.289098] [<
ffffffff9459c07e>] __kmalloc+0x13e/0x250
[ 3.289378] [<
ffffffff95078e5a>] scsi_alloc_sdev+0xea/0xcf0
[ 3.289701] [<
ffffffff9507de76>] __scsi_scan_target+0xa06/0xdf0
[ 3.290034] [<
ffffffff9507e505>] scsi_scan_channel+0x105/0x160
[ 3.290362] [<
ffffffff9507e8a2>] scsi_scan_host_selected+0x212/0x2f0
[ 3.290724] [<
ffffffff9507eb3c>] do_scsi_scan_host+0x1bc/0x250
[ 3.291055] [<
ffffffff9507efc1>] do_scan_async+0x41/0x450
[ 3.291354] [<
ffffffff941c1fee>] async_run_entry_fn+0xfe/0x610
[ 3.291695] [<
ffffffff941a9a84>] process_one_work+0x544/0x12d0
[ 3.292022] [<
ffffffff941aa8e9>] worker_thread+0xd9/0x12f0
[ 3.292325] [<
ffffffff941bb365>] kthread+0x1c5/0x260
[ 3.292594] [<
ffffffff956dde9f>] ret_from_fork+0x1f/0x40
[ 3.292886] Freed:
[ 3.292945] PID = 27
[ 3.293016] [<
ffffffff940b27ab>] save_stack_trace+0x2b/0x50
[ 3.293327] [<
ffffffff9459f246>] save_stack+0x46/0xd0
[ 3.293600] [<
ffffffff9459fa61>] kasan_slab_free+0x71/0xb0
[ 3.293916] [<
ffffffff9459bac2>] kfree+0xa2/0x1f0
[ 3.294168] [<
ffffffff9508158a>] scsi_device_dev_release_usercontext+0x50a/0x730
[ 3.294598] [<
ffffffff941ace9a>] execute_in_process_context+0xda/0x130
[ 3.294974] [<
ffffffff9508107c>] scsi_device_dev_release+0x1c/0x20
[ 3.295322] [<
ffffffff94f566f6>] device_release+0x76/0x1e0
[ 3.295626] [<
ffffffff94bc2db7>] kobject_release+0x107/0x370
[ 3.295942] [<
ffffffff94bc29ce>] kobject_put+0x4e/0xa0
[ 3.296222] [<
ffffffff94f56e17>] put_device+0x17/0x20
[ 3.296497] [<
ffffffff9505201c>] scsi_device_put+0x7c/0xa0
[ 3.296801] [<
ffffffff9507e1bc>] __scsi_scan_target+0xd4c/0xdf0
[ 3.297132] [<
ffffffff9507e505>] scsi_scan_channel+0x105/0x160
[ 3.297458] [<
ffffffff9507e8a2>] scsi_scan_host_selected+0x212/0x2f0
[ 3.297829] [<
ffffffff9507eb3c>] do_scsi_scan_host+0x1bc/0x250
[ 3.298156] [<
ffffffff9507efc1>] do_scan_async+0x41/0x450
[ 3.298453] [<
ffffffff941c1fee>] async_run_entry_fn+0xfe/0x610
[ 3.298777] [<
ffffffff941a9a84>] process_one_work+0x544/0x12d0
[ 3.299105] [<
ffffffff941aa8e9>] worker_thread+0xd9/0x12f0
[ 3.299408] [<
ffffffff941bb365>] kthread+0x1c5/0x260
[ 3.299676] [<
ffffffff956dde9f>] ret_from_fork+0x1f/0x40
[ 3.299967] Memory state around the buggy address:
[ 3.300209]
ffff880254d8c200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 3.300608]
ffff880254d8c280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 3.300986] >
ffff880254d8c300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 3.301408] ^
[ 3.301550]
ffff880254d8c380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 3.301987]
ffff880254d8c400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 3.302396]
==================================================================
Cc: Christoph Hellwig <hch@lst.de>
Cc: stable@vger.kernel.org
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>