Thread (20 messages) 20 messages, 4 authors, 2024-08-26

Re: [PATCH] wifi: ath6kl: Check that the read operation returns a data length of 0

From: Edward Adam Davis <hidden>
Date: 2024-08-25 14:09:03
Also in: linux-usb, linux-wireless, lkml
Subsystem: atheros ath generic utilities, atheros ath6kl wireless driver, the rest · Maintainers: Jeff Johnson, Linus Torvalds

On Sun, 25 Aug 2024 13:25:56 +0200, Greg KH wrote:
On Sun, Aug 25, 2024 at 06:09:45PM +0800, Edward Adam Davis wrote:
quoted
On Sun, 25 Aug 2024 10:34:00 +0200, Greg KH wrote:
quoted
On Sun, Aug 25, 2024 at 04:14:17PM +0800, Edward Adam Davis wrote:
quoted
On Sun, 25 Aug 2024 09:25:37 +0200, Greg KH wrote:
quoted
quoted
If the data length returned by the device is 0, the read operation
should be considered a failure.

Reported-and-tested-by: syzbot+92c6dd14aaa230be6855@syzkaller.appspotmail.com
Signed-off-by: Edward Adam Davis <redacted>
---
 drivers/net/wireless/ath/ath6kl/usb.c | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
index 5220809841a6..2a89bab81b24 100644
--- a/drivers/net/wireless/ath/ath6kl/usb.c
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
@@ -1034,6 +1034,9 @@ static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
 		ath6kl_err("Unable to read the bmi data from the device: %d\n",
 			   ret);
 		return ret;
+	} else {
+		ath6kl_err("Actual read the bmi data length is 0 from the device\n");
+		return -EIO;
Close, but not quite there.  ath6kl_usb_submit_ctrl_in() needs to verify
that the actual amount of data was read that was asked for.  If a short
read happens (or a long one), then an error needs to propagate out, not
just 0.  See the "note:" line in that function for what needs to be
properly checked.

hope this helps,
Thanks for your analysis.
I have carefully read your analysis and I am not sure if the following
understanding is appropriate:
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
index 2a89bab81b24..35884316a8c8 100644
--- a/drivers/net/wireless/ath/ath6kl/usb.c
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
@@ -932,6 +932,15 @@ static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb,

        kfree(buf);
First off, this should be using usb_control_msg_send() instead of having
to roll their own buffer handling, right?
I couldn't figure it out with what you said. 
Meaning this kfree() should not be needed if you use
usb_control_msg_send() (nor the allocation above it.)
quoted
ath6kl_usb_submit_ctrl_in() is similar to usb_control_msg_send(),
both calling usb_control_msg() to communicate with USB devices.
Yes, it's close, but not quite the same.
quoted
In the current issue, when executing an ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP
read request, the length of the data returned from the device is 0, which
is different from the expected length of the data to be read, resulting in
a warning.

ath6kl_usb_submit_ctrl_in()--->
	usb_control_msg()--->
		usb_internal_control_msg()

usb_internal_control_msg() will return the length of the data returned from
the device, usb_control_msg() return the length too, so in ath6kl_usb_submit_ctrl_in(),
we can filter out incorrect data lengths by judging the value of ret, such
as ret != Size situation.
Then just do that type of check for that type of read request in the
code that does that call, not 2-3 layers deeper, no need for making this
more complex than needed.

Try removing both of these functions and just call usb functions
directly.
I have tried following fix:
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
index 5220809841a6..dc1f89ebb740 100644
--- a/drivers/net/wireless/ath/ath6kl/usb.c
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
@@ -1027,9 +1027,9 @@ static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
        int ret;
 
        /* get response */
-       ret = ath6kl_usb_submit_ctrl_in(ar_usb,
-                                       ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP,
-                                       0, 0, buf, len);
+       ret = usb_control_msg_recv(ar_usb->udev, 0, ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP,
+                                USB_DIR_IN | USB_TYPE_VENDOR |
+                                USB_RECIP_DEVICE, 0, 0, buf, len, 2000, GFP_KERNEL);
        if (ret) {
                ath6kl_err("Unable to read the bmi data from the device: %d\n",
                           ret);
I researched usb_control_msg_recv(), It handles the abnormal length of the
returned data, so using it directly can fix this warning.

BR,
Edward
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help