]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.8.5/scsi-fix-use-after-free.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.8.5 / scsi-fix-use-after-free.patch
1 From bcd8f2e94808fcddf6ef3af5f060a36820dcc432 Mon Sep 17 00:00:00 2001
2 From: Ming Lei <tom.leiming@gmail.com>
3 Date: Sun, 9 Oct 2016 13:23:27 +0800
4 Subject: scsi: Fix use-after-free
5
6 From: Ming Lei <tom.leiming@gmail.com>
7
8 commit bcd8f2e94808fcddf6ef3af5f060a36820dcc432 upstream.
9
10 This patch fixes one use-after-free report[1] by KASAN.
11
12 In __scsi_scan_target(), when a type 31 device is probed,
13 SCSI_SCAN_TARGET_PRESENT is returned and the target will be scanned
14 again.
15
16 Inside the following scsi_report_lun_scan(), one new scsi_device
17 instance is allocated, and scsi_probe_and_add_lun() is called again to
18 probe the target and still see type 31 device, finally
19 __scsi_remove_device() is called to remove & free the device at the end
20 of scsi_probe_and_add_lun(), so cause use-after-free in
21 scsi_report_lun_scan().
22
23 And the following SCSI log can be observed:
24
25 scsi 0:0:2:0: scsi scan: INQUIRY pass 1 length 36
26 scsi 0:0:2:0: scsi scan: INQUIRY successful with code 0x0
27 scsi 0:0:2:0: scsi scan: peripheral device type of 31, no device added
28 scsi 0:0:2:0: scsi scan: Sending REPORT LUNS to (try 0)
29 scsi 0:0:2:0: scsi scan: REPORT LUNS successful (try 0) result 0x0
30 scsi 0:0:2:0: scsi scan: REPORT LUN scan
31 scsi 0:0:2:0: scsi scan: INQUIRY pass 1 length 36
32 scsi 0:0:2:0: scsi scan: INQUIRY successful with code 0x0
33 scsi 0:0:2:0: scsi scan: peripheral device type of 31, no device added
34 BUG: KASAN: use-after-free in __scsi_scan_target+0xbf8/0xe40 at addr ffff88007b44a104
35
36 This patch fixes the issue by moving the putting reference at
37 the end of scsi_report_lun_scan().
38
39 [1] KASAN report
40 ==================================================================
41 [ 3.274597] PM: Adding info for serio:serio1
42 [ 3.275127] BUG: KASAN: use-after-free in __scsi_scan_target+0xd87/0xdf0 at addr ffff880254d8c304
43 [ 3.275653] Read of size 4 by task kworker/u10:0/27
44 [ 3.275903] CPU: 3 PID: 27 Comm: kworker/u10:0 Not tainted 4.8.0 #2121
45 [ 3.276258] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
46 [ 3.276797] Workqueue: events_unbound async_run_entry_fn
47 [ 3.277083] ffff880254d8c380 ffff880259a37870 ffffffff94bbc6c1 ffff880078402d80
48 [ 3.277532] ffff880254d8bb80 ffff880259a37898 ffffffff9459fec1 ffff880259a37930
49 [ 3.277989] ffff880254d8bb80 ffff880078402d80 ffff880259a37920 ffffffff945a0165
50 [ 3.278436] Call Trace:
51 [ 3.278528] [<ffffffff94bbc6c1>] dump_stack+0x65/0x84
52 [ 3.278797] [<ffffffff9459fec1>] kasan_object_err+0x21/0x70
53 [ 3.279063] device: 'psaux': device_add
54 [ 3.279616] [<ffffffff945a0165>] kasan_report_error+0x205/0x500
55 [ 3.279651] PM: Adding info for No Bus:psaux
56 [ 3.280202] [<ffffffff944ecd22>] ? kfree_const+0x22/0x30
57 [ 3.280486] [<ffffffff94bc2dc9>] ? kobject_release+0x119/0x370
58 [ 3.280805] [<ffffffff945a0543>] __asan_report_load4_noabort+0x43/0x50
59 [ 3.281170] [<ffffffff9507e1f7>] ? __scsi_scan_target+0xd87/0xdf0
60 [ 3.281506] [<ffffffff9507e1f7>] __scsi_scan_target+0xd87/0xdf0
61 [ 3.281848] [<ffffffff9507d470>] ? scsi_add_device+0x30/0x30
62 [ 3.282156] [<ffffffff94f7f660>] ? pm_runtime_autosuspend_expiration+0x60/0x60
63 [ 3.282570] [<ffffffff956ddb07>] ? _raw_spin_lock+0x17/0x40
64 [ 3.282880] [<ffffffff9507e505>] scsi_scan_channel+0x105/0x160
65 [ 3.283200] [<ffffffff9507e8a2>] scsi_scan_host_selected+0x212/0x2f0
66 [ 3.283563] [<ffffffff9507eb3c>] do_scsi_scan_host+0x1bc/0x250
67 [ 3.283882] [<ffffffff9507efc1>] do_scan_async+0x41/0x450
68 [ 3.284173] [<ffffffff941c1fee>] async_run_entry_fn+0xfe/0x610
69 [ 3.284492] [<ffffffff941a8954>] ? pwq_dec_nr_in_flight+0x124/0x2a0
70 [ 3.284876] [<ffffffff941d1770>] ? preempt_count_add+0x130/0x160
71 [ 3.285207] [<ffffffff941a9a84>] process_one_work+0x544/0x12d0
72 [ 3.285526] [<ffffffff941aa8e9>] worker_thread+0xd9/0x12f0
73 [ 3.285844] [<ffffffff941aa810>] ? process_one_work+0x12d0/0x12d0
74 [ 3.286182] [<ffffffff941bb365>] kthread+0x1c5/0x260
75 [ 3.286443] [<ffffffff940855cd>] ? __switch_to+0x88d/0x1430
76 [ 3.286745] [<ffffffff941bb1a0>] ? kthread_worker_fn+0x5a0/0x5a0
77 [ 3.287085] [<ffffffff956dde9f>] ret_from_fork+0x1f/0x40
78 [ 3.287368] [<ffffffff941bb1a0>] ? kthread_worker_fn+0x5a0/0x5a0
79 [ 3.287697] Object at ffff880254d8bb80, in cache kmalloc-2048 size: 2048
80 [ 3.288064] Allocated:
81 [ 3.288147] PID = 27
82 [ 3.288218] [<ffffffff940b27ab>] save_stack_trace+0x2b/0x50
83 [ 3.288531] [<ffffffff9459f246>] save_stack+0x46/0xd0
84 [ 3.288806] [<ffffffff9459f4bd>] kasan_kmalloc+0xad/0xe0
85 [ 3.289098] [<ffffffff9459c07e>] __kmalloc+0x13e/0x250
86 [ 3.289378] [<ffffffff95078e5a>] scsi_alloc_sdev+0xea/0xcf0
87 [ 3.289701] [<ffffffff9507de76>] __scsi_scan_target+0xa06/0xdf0
88 [ 3.290034] [<ffffffff9507e505>] scsi_scan_channel+0x105/0x160
89 [ 3.290362] [<ffffffff9507e8a2>] scsi_scan_host_selected+0x212/0x2f0
90 [ 3.290724] [<ffffffff9507eb3c>] do_scsi_scan_host+0x1bc/0x250
91 [ 3.291055] [<ffffffff9507efc1>] do_scan_async+0x41/0x450
92 [ 3.291354] [<ffffffff941c1fee>] async_run_entry_fn+0xfe/0x610
93 [ 3.291695] [<ffffffff941a9a84>] process_one_work+0x544/0x12d0
94 [ 3.292022] [<ffffffff941aa8e9>] worker_thread+0xd9/0x12f0
95 [ 3.292325] [<ffffffff941bb365>] kthread+0x1c5/0x260
96 [ 3.292594] [<ffffffff956dde9f>] ret_from_fork+0x1f/0x40
97 [ 3.292886] Freed:
98 [ 3.292945] PID = 27
99 [ 3.293016] [<ffffffff940b27ab>] save_stack_trace+0x2b/0x50
100 [ 3.293327] [<ffffffff9459f246>] save_stack+0x46/0xd0
101 [ 3.293600] [<ffffffff9459fa61>] kasan_slab_free+0x71/0xb0
102 [ 3.293916] [<ffffffff9459bac2>] kfree+0xa2/0x1f0
103 [ 3.294168] [<ffffffff9508158a>] scsi_device_dev_release_usercontext+0x50a/0x730
104 [ 3.294598] [<ffffffff941ace9a>] execute_in_process_context+0xda/0x130
105 [ 3.294974] [<ffffffff9508107c>] scsi_device_dev_release+0x1c/0x20
106 [ 3.295322] [<ffffffff94f566f6>] device_release+0x76/0x1e0
107 [ 3.295626] [<ffffffff94bc2db7>] kobject_release+0x107/0x370
108 [ 3.295942] [<ffffffff94bc29ce>] kobject_put+0x4e/0xa0
109 [ 3.296222] [<ffffffff94f56e17>] put_device+0x17/0x20
110 [ 3.296497] [<ffffffff9505201c>] scsi_device_put+0x7c/0xa0
111 [ 3.296801] [<ffffffff9507e1bc>] __scsi_scan_target+0xd4c/0xdf0
112 [ 3.297132] [<ffffffff9507e505>] scsi_scan_channel+0x105/0x160
113 [ 3.297458] [<ffffffff9507e8a2>] scsi_scan_host_selected+0x212/0x2f0
114 [ 3.297829] [<ffffffff9507eb3c>] do_scsi_scan_host+0x1bc/0x250
115 [ 3.298156] [<ffffffff9507efc1>] do_scan_async+0x41/0x450
116 [ 3.298453] [<ffffffff941c1fee>] async_run_entry_fn+0xfe/0x610
117 [ 3.298777] [<ffffffff941a9a84>] process_one_work+0x544/0x12d0
118 [ 3.299105] [<ffffffff941aa8e9>] worker_thread+0xd9/0x12f0
119 [ 3.299408] [<ffffffff941bb365>] kthread+0x1c5/0x260
120 [ 3.299676] [<ffffffff956dde9f>] ret_from_fork+0x1f/0x40
121 [ 3.299967] Memory state around the buggy address:
122 [ 3.300209] ffff880254d8c200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
123 [ 3.300608] ffff880254d8c280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
124 [ 3.300986] >ffff880254d8c300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
125 [ 3.301408] ^
126 [ 3.301550] ffff880254d8c380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
127 [ 3.301987] ffff880254d8c400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
128 [ 3.302396]
129 ==================================================================
130
131 Cc: Christoph Hellwig <hch@lst.de>
132 Signed-off-by: Ming Lei <tom.leiming@gmail.com>
133 Reviewed-by: Christoph Hellwig <hch@lst.de>
134 Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
135 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
136
137 ---
138 drivers/scsi/scsi_scan.c | 2 +-
139 1 file changed, 1 insertion(+), 1 deletion(-)
140
141 --- a/drivers/scsi/scsi_scan.c
142 +++ b/drivers/scsi/scsi_scan.c
143 @@ -1472,12 +1472,12 @@ retry:
144 out_err:
145 kfree(lun_data);
146 out:
147 - scsi_device_put(sdev);
148 if (scsi_device_created(sdev))
149 /*
150 * the sdev we used didn't appear in the report luns scan
151 */
152 __scsi_remove_device(sdev);
153 + scsi_device_put(sdev);
154 return ret;
155 }
156