From: Larry Finger <Larry.Finger@xxxxxxxxxxxx> In map_urb_for_dma(), the DMA address returned by dma_map_single() is not checked to determine if it is legal. This lack of checking contributed to a problem with the libertas wireless driver (http://marc.info/?l=linux-wireless&m=125695331205062&w=2). The difficulty was not detected until the buffer was unmapped. By this time memory corruption had occurred. The situation is fixed by testing the returned DMA address, and returning -EAGAIN if the address is invalid. Signed-off-by: Larry Finger <Larry.Finger@xxxxxxxxxxxx> Cc: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx> --- drivers/usb/core/hcd.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 34de475..026ab2f 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1275,13 +1275,16 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, if (usb_endpoint_xfer_control(&urb->ep->desc) && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { - if (hcd->self.uses_dma) + if (hcd->self.uses_dma) { urb->setup_dma = dma_map_single( hcd->self.controller, urb->setup_packet, sizeof(struct usb_ctrlrequest), DMA_TO_DEVICE); - else if (hcd->driver->flags & HCD_LOCAL_MEM) + if (dma_mapping_error(hcd->self.controller, + urb->setup_dma)) + return -EAGAIN; + } else if (hcd->driver->flags & HCD_LOCAL_MEM) ret = hcd_alloc_coherent( urb->dev->bus, mem_flags, &urb->setup_dma, @@ -1293,13 +1296,16 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; if (ret == 0 && urb->transfer_buffer_length != 0 && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { - if (hcd->self.uses_dma) + if (hcd->self.uses_dma) { urb->transfer_dma = dma_map_single ( hcd->self.controller, urb->transfer_buffer, urb->transfer_buffer_length, dir); - else if (hcd->driver->flags & HCD_LOCAL_MEM) { + if (dma_mapping_error(hcd->self.controller, + urb->transfer_dma)) + return -EAGAIN; + } else if (hcd->driver->flags & HCD_LOCAL_MEM) { ret = hcd_alloc_coherent( urb->dev->bus, mem_flags, &urb->transfer_dma, -- 1.6.5.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html