diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2013-07-08 04:27:23 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-11 21:35:22 -0400 |
commit | 6bc14767620b9ef79140de5fe73cd25006e2da5f (patch) | |
tree | 6f6b6f5df3d492f8a9fac8218f4d002ef4bf460c | |
parent | 4008b2c77e1b7175d3ed17e99e1afdc0ec531427 (diff) |
Bluetooth: ath3k: don't use stack memory for DMA
commit 517828a87994f41af6ae5a0f96f0f069f05baa81 upstream.
Memory allocated by vmalloc (including stack) can not be used for DMA,
i.e. data pointer on usb_control_msg() should not point to stack memory.
Resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=977558
Reported-and-tested-by: Andy Lawrence <dr.diesel@gmail.com>
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/bluetooth/ath3k.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index b22376dee2c0..6f17e4dec441 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -195,24 +195,44 @@ error: | |||
195 | 195 | ||
196 | static int ath3k_get_state(struct usb_device *udev, unsigned char *state) | 196 | static int ath3k_get_state(struct usb_device *udev, unsigned char *state) |
197 | { | 197 | { |
198 | int pipe = 0; | 198 | int ret, pipe = 0; |
199 | char *buf; | ||
200 | |||
201 | buf = kmalloc(sizeof(*buf), GFP_KERNEL); | ||
202 | if (!buf) | ||
203 | return -ENOMEM; | ||
199 | 204 | ||
200 | pipe = usb_rcvctrlpipe(udev, 0); | 205 | pipe = usb_rcvctrlpipe(udev, 0); |
201 | return usb_control_msg(udev, pipe, ATH3K_GETSTATE, | 206 | ret = usb_control_msg(udev, pipe, ATH3K_GETSTATE, |
202 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, | 207 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, |
203 | state, 0x01, USB_CTRL_SET_TIMEOUT); | 208 | buf, sizeof(*buf), USB_CTRL_SET_TIMEOUT); |
209 | |||
210 | *state = *buf; | ||
211 | kfree(buf); | ||
212 | |||
213 | return ret; | ||
204 | } | 214 | } |
205 | 215 | ||
206 | static int ath3k_get_version(struct usb_device *udev, | 216 | static int ath3k_get_version(struct usb_device *udev, |
207 | struct ath3k_version *version) | 217 | struct ath3k_version *version) |
208 | { | 218 | { |
209 | int pipe = 0; | 219 | int ret, pipe = 0; |
220 | struct ath3k_version *buf; | ||
221 | const int size = sizeof(*buf); | ||
222 | |||
223 | buf = kmalloc(size, GFP_KERNEL); | ||
224 | if (!buf) | ||
225 | return -ENOMEM; | ||
210 | 226 | ||
211 | pipe = usb_rcvctrlpipe(udev, 0); | 227 | pipe = usb_rcvctrlpipe(udev, 0); |
212 | return usb_control_msg(udev, pipe, ATH3K_GETVERSION, | 228 | ret = usb_control_msg(udev, pipe, ATH3K_GETVERSION, |
213 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version, | 229 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, |
214 | sizeof(struct ath3k_version), | 230 | buf, size, USB_CTRL_SET_TIMEOUT); |
215 | USB_CTRL_SET_TIMEOUT); | 231 | |
232 | memcpy(version, buf, size); | ||
233 | kfree(buf); | ||
234 | |||
235 | return ret; | ||
216 | } | 236 | } |
217 | 237 | ||
218 | static int ath3k_load_fwfile(struct usb_device *udev, | 238 | static int ath3k_load_fwfile(struct usb_device *udev, |