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 10:21:06
Also in: linux-usb, linux-wireless, lkml

On Sun, 25 Aug 2024 10:34:00 +0200, Greg KH wrote:
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. 

ath6kl_usb_submit_ctrl_in() is similar to usb_control_msg_send(),
both calling usb_control_msg() to communicate with USB devices.

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.
quoted
+       /* There are two types of read failure situations that need to be captured:
+        * 1. short read: ret < size && ret >= 0
+        * 2. long read: ret > size
+        * */
+       if (req == ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP && ret != size) {
+               ath6kl_warn("Actual read the data length is: %d, but input size is %d\n", ret, size);
+               return -EIO;
+       }
If you switch to usb_control_msg_send() this logic gets a lot simpler.
Perhaps do that instead?

If not, then you need to check for "short writes" or zero writes, see
the documentation for usb_control_msg() for what it returns.  Your
comment is not correct here, there are 3 different return "states" that
you need to handle.

And why are you caring about what the req type is?
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