3514094
Memory allocated by vmalloc (including stack) can not be used for DMA,
3514094
i.e. data pointer on usb_control_msg() should not point to stack memory.
3514094
3514094
Resolves:
3514094
https://bugzilla.redhat.com/show_bug.cgi?id=977558
3514094
3514094
Reported-and-tested-by: Andy Lawrence <dr.diesel@gmail.com>
3514094
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
3514094
---
3514094
 drivers/bluetooth/ath3k.c | 38 +++++++++++++++++++++++++++++---------
3514094
 1 file changed, 29 insertions(+), 9 deletions(-)
3514094
3514094
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
3514094
index 11f467c..81b636c 100644
3514094
--- a/drivers/bluetooth/ath3k.c
3514094
+++ b/drivers/bluetooth/ath3k.c
3514094
@@ -193,24 +193,44 @@ error:
3514094
 
3514094
 static int ath3k_get_state(struct usb_device *udev, unsigned char *state)
3514094
 {
3514094
-	int pipe = 0;
3514094
+	int ret, pipe = 0;
3514094
+	char *buf;
3514094
+
3514094
+	buf = kmalloc(1, GFP_KERNEL);
3514094
+	if (!buf)
3514094
+		return -ENOMEM;
3514094
 
3514094
 	pipe = usb_rcvctrlpipe(udev, 0);
3514094
-	return usb_control_msg(udev, pipe, ATH3K_GETSTATE,
3514094
-			USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
3514094
-			state, 0x01, USB_CTRL_SET_TIMEOUT);
3514094
+	ret = usb_control_msg(udev, pipe, ATH3K_GETSTATE,
3514094
+			      USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
3514094
+			      buf, 1, USB_CTRL_SET_TIMEOUT);
3514094
+
3514094
+	*state = *buf;
3514094
+	kfree(buf);
3514094
+
3514094
+	return ret;
3514094
 }
3514094
 
3514094
 static int ath3k_get_version(struct usb_device *udev,
3514094
 			struct ath3k_version *version)
3514094
 {
3514094
-	int pipe = 0;
3514094
+	int ret, pipe = 0;
3514094
+	char *buf;
3514094
+	const int size = sizeof(struct ath3k_version);
3514094
+	
3514094
+	buf = kmalloc(size, GFP_KERNEL);
3514094
+	if (!buf)
3514094
+		return -ENOMEM;
3514094
 
3514094
 	pipe = usb_rcvctrlpipe(udev, 0);
3514094
-	return usb_control_msg(udev, pipe, ATH3K_GETVERSION,
3514094
-			USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version,
3514094
-			sizeof(struct ath3k_version),
3514094
-			USB_CTRL_SET_TIMEOUT);
3514094
+	ret = usb_control_msg(udev, pipe, ATH3K_GETVERSION,
3514094
+			      USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
3514094
+			      buf, size, USB_CTRL_SET_TIMEOUT);
3514094
+
3514094
+	memcpy(version, buf, size);
3514094
+	kfree(buf);
3514094
+
3514094
+	return ret;
3514094
 }
3514094
 
3514094
 static int ath3k_load_fwfile(struct usb_device *udev,
3514094
-- 
3514094
1.7.11.7