lkml.org 
[lkml]   [2016]   [Oct]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.8 083/140] scsi: Fix use-after-free
    Date
    4.8-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Ming Lei <tom.leiming@gmail.com>

    commit bcd8f2e94808fcddf6ef3af5f060a36820dcc432 upstream.

    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>
    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>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/scsi/scsi_scan.c | 2 +-
    1 file changed, 1 insertion(+), 1 deletion(-)

    --- a/drivers/scsi/scsi_scan.c
    +++ b/drivers/scsi/scsi_scan.c
    @@ -1472,12 +1472,12 @@ retry:
    out_err:
    kfree(lun_data);
    out:
    - scsi_device_put(sdev);
    if (scsi_device_created(sdev))
    /*
    * the sdev we used didn't appear in the report luns scan
    */
    __scsi_remove_device(sdev);
    + scsi_device_put(sdev);
    return ret;
    }


    \
     
     \ /
      Last update: 2016-10-26 15:13    [W:3.974 / U:0.600 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site