Skip to content

Commit 8fe0618

Browse files
Xu Yanggregkh
authored andcommitted
usb: core: hcd: fix accessing unmapped memory in SINGLE_STEP_SET_FEATURE test
The USB core will unmap urb->transfer_dma after SETUP stage completes. Then the USB controller will access unmapped memory when it received device descriptor. If iommu is equipped, the entire test can't be completed due to the memory accessing is blocked. Fix it by calling map_urb_for_dma() again for IN stage. To reduce redundant map for urb->transfer_buffer, this will also set URB_NO_TRANSFER_DMA_MAP flag before first map_urb_for_dma() to skip dma map for urb->transfer_buffer and clear URB_NO_TRANSFER_DMA_MAP flag before second map_urb_for_dma(). Fixes: 216e0e5 ("usb: core: hcd: use map_urb_for_dma for single step set feature urb") Cc: stable <[email protected]> Reviewed-by: Jun Li <[email protected]> Signed-off-by: Xu Yang <[email protected]> Acked-by: Alan Stern <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent f9420f4 commit 8fe0618

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

drivers/usb/core/hcd.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2166,7 +2166,7 @@ static struct urb *request_single_step_set_feature_urb(
21662166
urb->complete = usb_ehset_completion;
21672167
urb->status = -EINPROGRESS;
21682168
urb->actual_length = 0;
2169-
urb->transfer_flags = URB_DIR_IN;
2169+
urb->transfer_flags = URB_DIR_IN | URB_NO_TRANSFER_DMA_MAP;
21702170
usb_get_urb(urb);
21712171
atomic_inc(&urb->use_count);
21722172
atomic_inc(&urb->dev->urbnum);
@@ -2230,9 +2230,15 @@ int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
22302230

22312231
/* Complete remaining DATA and STATUS stages using the same URB */
22322232
urb->status = -EINPROGRESS;
2233+
urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP;
22332234
usb_get_urb(urb);
22342235
atomic_inc(&urb->use_count);
22352236
atomic_inc(&urb->dev->urbnum);
2237+
if (map_urb_for_dma(hcd, urb, GFP_KERNEL)) {
2238+
usb_put_urb(urb);
2239+
goto out1;
2240+
}
2241+
22362242
retval = hcd->driver->submit_single_step_set_feature(hcd, urb, 0);
22372243
if (!retval && !wait_for_completion_timeout(&done,
22382244
msecs_to_jiffies(2000))) {

0 commit comments

Comments
 (0)