Thread (5 messages) 5 messages, 2 authors, 2021-10-18

Re: [PATCH v2 1/2] HID: u2fzero: explicitly check for errors

From: Alan Stern <stern@rowland.harvard.edu>
Date: 2021-10-18 14:38:32
Also in: linux-input, linux-usb

On Mon, Oct 18, 2021 at 04:17:57PM +0200, Andrej Shadura wrote:
On 18/10/2021 16:15, Alan Stern wrote:
quoted
On Mon, Oct 18, 2021 at 02:21:43PM +0200, Andrej Shadura wrote:
quoted
The previous commit fixed handling of incomplete packets but broke error
handling: offsetof returns an unsigned value (size_t), but when compared
against the signed return value, the return value is interpreted as if
it were unsigned, so negative return values are never less than the
offset.

Fixes: 22d65765f211 ("HID: u2fzero: ignore incomplete packets without data")
Fixes: 42337b9d4d95 ("HID: add driver for U2F Zero built-in LED and RNG")
Signed-off-by: Andrej Shadura <redacted>
---
  drivers/hid/hid-u2fzero.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hid/hid-u2fzero.c b/drivers/hid/hid-u2fzero.c
index d70cd3d7f583..5145d758bea0 100644
--- a/drivers/hid/hid-u2fzero.c
+++ b/drivers/hid/hid-u2fzero.c
@@ -200,7 +200,7 @@ static int u2fzero_rng_read(struct hwrng *rng, void *data,
  	ret = u2fzero_recv(dev, &req, &resp);
  	/* ignore errors or packets without data */
-	if (ret < offsetof(struct u2f_hid_msg, init.data))
+	if (ret < 0 || ret < offsetof(struct u2f_hid_msg, init.data))
Although the patch description does a good job of explaining what's
happening, someone merely reading the code will most likely not
understand.

One alternative is to add a comment.  Another is simply to force a
signed integer comparison:

	if (ret < (ssize_t) offsetof(...
I have considered that, but I thought that is actually less readable than
having two conditions. I’m curious that you say "ignore errors or packets
without data" is not clear enough — how would you reword that without
inflating it too much?
You misunderstand.  The existing comment is clear enough.  But the code 
itself is misleading:

	if (ret < 0 || ret < offsetof(...

looks redundant.  Someone reading it for the first time will 
automatically think: "If ret < 0 then certainly it is < the offset of 
some internal field.  So why perform two comparisons when one is 
enough?"

To help such a reader understand what is happening, you could add a 
comment like:

	/*
	 * offsetof returns an unsigned value, so the comparison with
	 * ret uses unsigned arithmetic and won't detect a negative
	 * error value.  We need a separate test for errors.
	 */

If you think a comment like this is preferable to a typecast, fine.

Another alternative is:

	ret -= offsetof(...);
	if (ret < 0)
		return 0;

which may look more complicated but allows you to simplify the max3 
computation in the next line.

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