Commit 9821aa9de97ccaaa16297d42a2c5a532c0032097
Committed by
Greg Kroah-Hartman
1 parent
cbf30a914e
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
USB: uss720: fix DMA-buffer allocation
Make sure the USB control request is allocated separately from containing structure to prevent potential memory corruption on non-cache-coherent systems. Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 1 changed file with 15 additions and 9 deletions Side-by-side Diff
drivers/usb/misc/uss720.c
... | ... | @@ -75,7 +75,7 @@ |
75 | 75 | struct list_head asynclist; |
76 | 76 | struct completion compl; |
77 | 77 | struct urb *urb; |
78 | - struct usb_ctrlrequest dr; | |
78 | + struct usb_ctrlrequest *dr; | |
79 | 79 | __u8 reg[7]; |
80 | 80 | }; |
81 | 81 | |
... | ... | @@ -98,6 +98,7 @@ |
98 | 98 | |
99 | 99 | if (likely(rq->urb)) |
100 | 100 | usb_free_urb(rq->urb); |
101 | + kfree(rq->dr); | |
101 | 102 | spin_lock_irqsave(&priv->asynclock, flags); |
102 | 103 | list_del_init(&rq->asynclist); |
103 | 104 | spin_unlock_irqrestore(&priv->asynclock, flags); |
... | ... | @@ -120,7 +121,7 @@ |
120 | 121 | if (status) { |
121 | 122 | dev_err(&urb->dev->dev, "async_complete: urb error %d\n", |
122 | 123 | status); |
123 | - } else if (rq->dr.bRequest == 3) { | |
124 | + } else if (rq->dr->bRequest == 3) { | |
124 | 125 | memcpy(priv->reg, rq->reg, sizeof(priv->reg)); |
125 | 126 | #if 0 |
126 | 127 | dev_dbg(&priv->usbdev->dev, |
... | ... | @@ -152,7 +153,7 @@ |
152 | 153 | usbdev = priv->usbdev; |
153 | 154 | if (!usbdev) |
154 | 155 | return NULL; |
155 | - rq = kmalloc(sizeof(struct uss720_async_request), mem_flags); | |
156 | + rq = kzalloc(sizeof(struct uss720_async_request), mem_flags); | |
156 | 157 | if (!rq) { |
157 | 158 | dev_err(&usbdev->dev, "submit_async_request out of memory\n"); |
158 | 159 | return NULL; |
159 | 160 | |
... | ... | @@ -168,13 +169,18 @@ |
168 | 169 | dev_err(&usbdev->dev, "submit_async_request out of memory\n"); |
169 | 170 | return NULL; |
170 | 171 | } |
171 | - rq->dr.bRequestType = requesttype; | |
172 | - rq->dr.bRequest = request; | |
173 | - rq->dr.wValue = cpu_to_le16(value); | |
174 | - rq->dr.wIndex = cpu_to_le16(index); | |
175 | - rq->dr.wLength = cpu_to_le16((request == 3) ? sizeof(rq->reg) : 0); | |
172 | + rq->dr = kmalloc(sizeof(*rq->dr), mem_flags); | |
173 | + if (!rq->dr) { | |
174 | + kref_put(&rq->ref_count, destroy_async); | |
175 | + return NULL; | |
176 | + } | |
177 | + rq->dr->bRequestType = requesttype; | |
178 | + rq->dr->bRequest = request; | |
179 | + rq->dr->wValue = cpu_to_le16(value); | |
180 | + rq->dr->wIndex = cpu_to_le16(index); | |
181 | + rq->dr->wLength = cpu_to_le16((request == 3) ? sizeof(rq->reg) : 0); | |
176 | 182 | usb_fill_control_urb(rq->urb, usbdev, (requesttype & 0x80) ? usb_rcvctrlpipe(usbdev, 0) : usb_sndctrlpipe(usbdev, 0), |
177 | - (unsigned char *)&rq->dr, | |
183 | + (unsigned char *)rq->dr, | |
178 | 184 | (request == 3) ? rq->reg : NULL, (request == 3) ? sizeof(rq->reg) : 0, async_complete, rq); |
179 | 185 | /* rq->urb->transfer_flags |= URB_ASYNC_UNLINK; */ |
180 | 186 | spin_lock_irqsave(&priv->asynclock, flags); |