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