@@ -1072,6 +1072,7 @@ static struct usb_request *cdnsp_gadget_ep_alloc_request(struct usb_ep *ep,
preq->epnum = pep->number;
preq->pep = pep;
+ INIT_LIST_HEAD(&preq->td.td_list);
trace_cdnsp_alloc_request(preq);
@@ -1120,11 +1121,17 @@ static int cdnsp_gadget_ep_queue(struct usb_ep *ep,
static int cdnsp_gadget_ep_dequeue(struct usb_ep *ep,
struct usb_request *request)
{
- struct cdnsp_ep *pep = to_cdnsp_ep(ep);
- struct cdnsp_device *pdev = pep->pdev;
+ struct cdnsp_ep *pep;
+ struct cdnsp_device *pdev;
unsigned long flags;
int ret;
+ if (!request || !ep)
+ return -EINVAL;
+
+ pep = to_cdnsp_ep(ep);
+ pdev = pep->pdev;
+
if (!pep->endpoint.desc) {
dev_err(pdev->dev,
"%s: can't dequeue to disabled endpoint\n",
@@ -705,6 +705,11 @@ int cdnsp_remove_request(struct cdnsp_device *pdev,
trace_cdnsp_remove_request_td(preq);
cur_td = &preq->td;
+
+ /* Prevent kernel crash caused by re-running usb_ep_dequeue */
+ if (list_empty(&cur_td->td_list))
+ return ret;
+
ep_ring = cdnsp_request_to_transfer_ring(pdev, preq);
/*
The crash appears in the following situations: 1. Call usb_ep_dequeue without calling usb_ep_queue first 2. Repeated call usb_ep_dequeue Below is the log of kernel crash when stopping USB FFS device: [ 1044.732419] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 ... [ 1044.946689] Call trace: [ 1044.949133] cdnsp_trb_in_td.constprop.0+0x4/0xd0 [cdns3] [ 1044.954545] cdnsp_gadget_ep_dequeue+0x88/0xf0 [cdns3] [ 1044.959695] usb_ep_dequeue+0x18/0x24 [ 1044.963366] functionfs_unbind+0x2c/0xb4 [usb_f_fs] [ 1044.968256] ffs_func_unbind+0x110/0x124 [usb_f_fs] [ 1044.973144] purge_configs_funcs+0x9c/0x124 [libcomposite] [ 1044.978646] configfs_composite_unbind+0x5c/0xbc [libcomposite] [ 1044.984581] usb_gadget_remove_driver+0x60/0xf4 [ 1044.989120] usb_gadget_unregister_driver+0x70/0xe4 [ 1044.994008] unregister_gadget_item+0x30/0x58 [libcomposite] [ 1044.999682] ffs_data_clear+0x144/0x158 [usb_f_fs] [ 1045.004483] ffs_data_closed+0xdc/0x174 [usb_f_fs] [ 1045.009283] ffs_ep0_release+0x14/0x24 [usb_f_fs] Signed-off-by: Jing Leng <3090101217@zju.edu.cn> --- drivers/usb/cdns3/cdnsp-gadget.c | 11 +++++++++-- drivers/usb/cdns3/cdnsp-ring.c | 5 +++++ 2 files changed, 14 insertions(+), 2 deletions(-)