Commit 9821aa9de97ccaaa16297d42a2c5a532c0032097

Authored by Johan Hovold
Committed by Greg Kroah-Hartman
1 parent cbf30a914e

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);