• J
    usb: dwc3: gadget: Free gadget structure only after freeing endpoints · bb9c74a5
    Jack Pham 提交于
    As part of commit e81a7018 ("usb: dwc3: allocate gadget structure
    dynamically") the dwc3_gadget_release() was added which will free
    the dwc->gadget structure upon the device's removal when
    usb_del_gadget_udc() is called in dwc3_gadget_exit().
    
    However, simply freeing the gadget results a dangling pointer
    situation: the endpoints created in dwc3_gadget_init_endpoints()
    have their dep->endpoint.ep_list members chained off the list_head
    anchored at dwc->gadget->ep_list.  Thus when dwc->gadget is freed,
    the first dwc3_ep in the list now has a dangling prev pointer and
    likewise for the next pointer of the dwc3_ep at the tail of the list.
    The dwc3_gadget_free_endpoints() that follows will result in a
    use-after-free when it calls list_del().
    
    This was caught by enabling KASAN and performing a driver unbind.
    The recent commit 568262bf ("usb: dwc3: core: Add shutdown
    callback for dwc3") also exposes this as a panic during shutdown.
    
    There are a few possibilities to fix this.  One could be to perform
    a list_del() of the gadget->ep_list itself which removes it from
    the rest of the dwc3_ep chain.
    
    Another approach is what this patch does, by splitting up the
    usb_del_gadget_udc() call into its separate "del" and "put"
    components.  This allows dwc3_gadget_free_endpoints() to be
    called before the gadget is finally freed with usb_put_gadget().
    
    Fixes: e81a7018 ("usb: dwc3: allocate gadget structure dynamically")
    Reviewed-by: NPeter Chen <peter.chen@kernel.org>
    Signed-off-by: NJack Pham <jackp@codeaurora.org>
    Link: https://lore.kernel.org/r/20210501093558.7375-1-jackp@codeaurora.orgSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    bb9c74a5
gadget.c 106.0 KB