mirror of
https://github.com/torvalds/linux.git
synced 2026-06-09 07:03:37 +02:00
usb: gadget: composite: don't queue OS desc request if req length is invalid
In OS descriptors handling, if ctrl->bRequestType is USB_RECIP_DEVICE and w_index != 0x4 or (w_value >> 8) is true, it will not reset req->length, but use the default value(-EOPNOTSUPP), and queue an OS desc request with an invalid req->length. It always happens on the platforms which use os_desc(for example: rk3366,rk3399), and cause kernel panic as follows(use dwc3 driver): Unable to handle kernel paging request at virtual address ffffffc0f7e00000 Internal error: Oops: 96000146 [#1] PREEMPT SMP PC is at __dma_clean_range+0x18/0x30 LR is at __swiotlb_map_page+0x50/0x64 Call trace: [<ffffffc0000930f8>] __dma_clean_range+0x18/0x30 [<ffffffc00062214c>] usb_gadget_map_request+0x134/0x1b0 [<ffffffc0005c289c>] __dwc3_ep0_do_control_data+0x110/0x14c [<ffffffc0005c2d38>] __dwc3_gadget_ep0_queue+0x198/0x1b8 [<ffffffc0005c2e18>] dwc3_gadget_ep0_queue+0xc0/0xe8 [<ffffffc00061cfec>] composite_ep0_queue.constprop.14+0x34/0x98 [<ffffffc00061dfb0>] composite_setup+0xf60/0x100c [<ffffffc0006204dc>] android_setup+0xd8/0x138 [<ffffffc0005c29a4>] dwc3_ep0_delegate_req+0x34/0x50 [<ffffffc0005c3534>] dwc3_ep0_interrupt+0x5dc/0xb58 [<ffffffc0005c0c3c>] dwc3_thread_interrupt+0x15c/0xa24 With this patch, the gadget driver will not queue a request and return immediately if req->length is invalid. And the usb controller driver can handle the unsupport request correctly. Change-Id: I60270d7c12fa190a99cd1079880a2f7167e7af27 Signed-off-by: Wu Liang feng <wulf@rock-chips.com>
This commit is contained in:
parent
5e393383bc
commit
06ed11d415
|
|
@ -1766,14 +1766,19 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
|||
}
|
||||
break;
|
||||
}
|
||||
req->length = value;
|
||||
req->context = cdev;
|
||||
req->zero = value < w_length;
|
||||
value = composite_ep0_queue(cdev, req, GFP_ATOMIC);
|
||||
if (value < 0) {
|
||||
DBG(cdev, "ep_queue --> %d\n", value);
|
||||
req->status = 0;
|
||||
composite_setup_complete(gadget->ep0, req);
|
||||
|
||||
if (value >= 0) {
|
||||
req->length = value;
|
||||
req->context = cdev;
|
||||
req->zero = value < w_length;
|
||||
value = composite_ep0_queue(cdev, req,
|
||||
GFP_ATOMIC);
|
||||
if (value < 0) {
|
||||
DBG(cdev, "ep_queue --> %d\n", value);
|
||||
req->status = 0;
|
||||
composite_setup_complete(gadget->ep0,
|
||||
req);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user