Commit b7abf78b authored by Andrej Shadura's avatar Andrej Shadura Committed by Jiri Kosina

HID: u2fzero: clarify error check and length calculations

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.

To make the code easier to read, calculate the minimal packet length
once and separately, and assign it to a signed int variable to eliminate
unsigned math and the need for type casts. It then becomes immediately
obvious how the actual data length is calculated and why the return
value cannot be less than the minimal length.

Fixes: 22d65765 ("HID: u2fzero: ignore incomplete packets without data")
Fixes: 42337b9d ("HID: add driver for U2F Zero built-in LED and RNG")
Signed-off-by: default avatarAndrej Shadura <andrew.shadura@collabora.co.uk>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 08b9a61a
...@@ -191,6 +191,8 @@ static int u2fzero_rng_read(struct hwrng *rng, void *data, ...@@ -191,6 +191,8 @@ static int u2fzero_rng_read(struct hwrng *rng, void *data,
struct u2f_hid_msg resp; struct u2f_hid_msg resp;
int ret; int ret;
size_t actual_length; size_t actual_length;
/* valid packets must have a correct header */
int min_length = offsetof(struct u2f_hid_msg, init.data);
if (!dev->present) { if (!dev->present) {
hid_dbg(dev->hdev, "device not present"); hid_dbg(dev->hdev, "device not present");
...@@ -200,12 +202,12 @@ static int u2fzero_rng_read(struct hwrng *rng, void *data, ...@@ -200,12 +202,12 @@ static int u2fzero_rng_read(struct hwrng *rng, void *data,
ret = u2fzero_recv(dev, &req, &resp); ret = u2fzero_recv(dev, &req, &resp);
/* ignore errors or packets without data */ /* ignore errors or packets without data */
if (ret < offsetof(struct u2f_hid_msg, init.data)) if (ret < min_length)
return 0; return 0;
/* only take the minimum amount of data it is safe to take */ /* only take the minimum amount of data it is safe to take */
actual_length = min3((size_t)ret - offsetof(struct u2f_hid_msg, actual_length = min3((size_t)ret - min_length,
init.data), U2F_HID_MSG_LEN(resp), max); U2F_HID_MSG_LEN(resp), max);
memcpy(data, resp.init.data, actual_length); memcpy(data, resp.init.data, actual_length);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment