• Hans Yang's avatar
    usb: core : hub: Fix BOS 'NULL pointer' kernel panic · 3eee4565
    Hans Yang authored
    commit 464ad8c4 upstream.
    
    When a USB 3.0 mass storage device is disconnected in transporting
    state, storage device driver may handle it as a transport error and
    reset the device by invoking usb_reset_and_verify_device()
    and following could happen:
    
    in usb_reset_and_verify_device():
       udev->bos = NULL;
    
    For U1/U2 enabled devices, driver will disable LPM, and in some
    conditions:
       from usb_unlocked_disable_lpm()
        --> usb_disable_lpm()
        --> usb_enable_lpm()
            udev->bos->ss_cap->bU1devExitLat;
    
    And it causes 'NULL pointer' and 'kernel panic':
    
    [  157.976257] Unable to handle kernel NULL pointer dereference
    at virtual address 00000010
    ...
    [  158.026400] PC is at usb_enable_link_state+0x34/0x2e0
    [  158.031442] LR is at usb_enable_lpm+0x98/0xac
    ...
    [  158.137368] [<ffffffc0006a1cac>] usb_enable_link_state+0x34/0x2e0
    [  158.143451] [<ffffffc0006a1fec>] usb_enable_lpm+0x94/0xac
    [  158.148840] [<ffffffc0006a20e8>] usb_disable_lpm+0xa8/0xb4
    ...
    [  158.214954] Kernel panic - not syncing: Fatal exception
    
    This commit moves 'udev->bos = NULL' behind usb_unlocked_disable_lpm()
    to prevent from NULL pointer access.
    
    Issue can be reproduced by following setup:
    1) A SS pen drive behind a SS hub connected to the host.
    2) Transporting data between the pen drive and the host.
    3) Abruptly disconnect hub and pen drive from host.
    4) With a chance it crashes.
    Signed-off-by: default avatarHans Yang <hansy@nvidia.com>
    Acked-by: default avatarAlan Stern <stern@rowland.harvard.edu>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
    3eee4565
hub.c 163 KB