Skip to content
  • Winter Wang's avatar
    usb: gadget: configfs: add mutex lock before unregister gadget · cee51c33
    Winter Wang authored
    There may be a race condition if f_fs calls unregister_gadget_item in
    ffs_closed() when unregister_gadget is called by UDC store at the same time.
    this leads to a kernel NULL pointer dereference:
    
    [  310.644928] Unable to handle kernel NULL pointer dereference at virtual address 00000004
    [  310.645053] init: Service 'adbd' is being killed...
    [  310.658938] pgd = c9528000
    [  310.662515] [00000004] *pgd=19451831, *pte=00000000, *ppte=00000000
    [  310.669702] Internal error: Oops: 817 [#1
    
    ] PREEMPT SMP ARM
    [  310.675211] Modules linked in:
    [  310.678294] CPU: 0 PID: 1537 Comm: ->transport Not tainted 4.1.15-03725-g793404c #2
    [  310.685958] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
    [  310.692493] task: c8e24200 ti: c945e000 task.ti: c945e000
    [  310.697911] PC is at usb_gadget_unregister_driver+0xb4/0xd0
    [  310.703502] LR is at __mutex_lock_slowpath+0x10c/0x16c
    [  310.708648] pc : [<c075efc0>]    lr : [<c0bfb0bc>]    psr: 600f0113
    <snip..>
    [  311.565585] [<c075efc0>] (usb_gadget_unregister_driver) from [<c075e2b8>] (unregister_gadget_item+0x1c/0x34)
    [  311.575426] [<c075e2b8>] (unregister_gadget_item) from [<c076fcc8>] (ffs_closed+0x8c/0x9c)
    [  311.583702] [<c076fcc8>] (ffs_closed) from [<c07736b8>] (ffs_data_reset+0xc/0xa0)
    [  311.591194] [<c07736b8>] (ffs_data_reset) from [<c07738ac>] (ffs_data_closed+0x90/0xd0)
    [  311.599208] [<c07738ac>] (ffs_data_closed) from [<c07738f8>] (ffs_ep0_release+0xc/0x14)
    [  311.607224] [<c07738f8>] (ffs_ep0_release) from [<c023e030>] (__fput+0x80/0x1d0)
    [  311.614635] [<c023e030>] (__fput) from [<c014e688>] (task_work_run+0xb0/0xe8)
    [  311.621788] [<c014e688>] (task_work_run) from [<c010afdc>] (do_work_pending+0x7c/0xa4)
    [  311.629718] [<c010afdc>] (do_work_pending) from [<c010770c>] (work_pending+0xc/0x20)
    
    for functions using functionFS, i.e. android adbd will close /dev/usb-ffs/adb/ep0
    when usb IO thread fails, but switch adb from on to off also triggers write
    "none" > UDC. These 2 operations both call unregister_gadget, which will lead
    to the panic above.
    
    add a mutex before calling unregister_gadget for api used in f_fs.
    
    Signed-off-by: default avatarWinter Wang <wente.wang@nxp.com>
    Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
    cee51c33