Skip to content

Commit 84dc708

Browse files
Xu Yanggregkh
authored andcommitted
usb: core: hcd: fix accessing unmapped memory in SINGLE_STEP_SET_FEATURE test
commit 8fe0618 upstream. 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 <stable@kernel.org> Reviewed-by: Jun Li <jun.li@nxp.com> Signed-off-by: Xu Yang <xu.yang_2@nxp.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Link: https://lore.kernel.org/r/20250806083955.3325299-1-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent aecf0d5 commit 84dc708

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
@@ -2151,7 +2151,7 @@ static struct urb *request_single_step_set_feature_urb(
21512151
urb->complete = usb_ehset_completion;
21522152
urb->status = -EINPROGRESS;
21532153
urb->actual_length = 0;
2154-
urb->transfer_flags = URB_DIR_IN;
2154+
urb->transfer_flags = URB_DIR_IN | URB_NO_TRANSFER_DMA_MAP;
21552155
usb_get_urb(urb);
21562156
atomic_inc(&urb->use_count);
21572157
atomic_inc(&urb->dev->urbnum);
@@ -2215,9 +2215,15 @@ int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
22152215

22162216
/* Complete remaining DATA and STATUS stages using the same URB */
22172217
urb->status = -EINPROGRESS;
2218+
urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP;
22182219
usb_get_urb(urb);
22192220
atomic_inc(&urb->use_count);
22202221
atomic_inc(&urb->dev->urbnum);
2222+
if (map_urb_for_dma(hcd, urb, GFP_KERNEL)) {
2223+
usb_put_urb(urb);
2224+
goto out1;
2225+
}
2226+
22212227
retval = hcd->driver->submit_single_step_set_feature(hcd, urb, 0);
22222228
if (!retval && !wait_for_completion_timeout(&done,
22232229
msecs_to_jiffies(2000))) {

0 commit comments

Comments
 (0)