Skip to content

Commit

Permalink
HID: i2c-hid: fix i2c_hid_get_raw_report count mismatches
Browse files Browse the repository at this point in the history
The previous memcpy implementation relied on the size advertized by the
device. There were no guarantees that buf was big enough.

Some gymnastic is also required with the +2/-2 to take into account
the first 2 bytes of the returned buffer where the total returned
length is supplied by the device.

Signed-off-by: Benjamin Tissoires <[email protected]>
Signed-off-by: Jiri Kosina <[email protected]>
  • Loading branch information
bentiss authored and Jiri Kosina committed Dec 6, 2012
1 parent 8a1bbb5 commit e5b50fe
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions drivers/hid/i2c-hid/i2c-hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,23 +502,31 @@ static int i2c_hid_get_raw_report(struct hid_device *hid,
{
struct i2c_client *client = hid->driver_data;
struct i2c_hid *ihid = i2c_get_clientdata(client);
size_t ret_count, ask_count;
int ret;

if (report_type == HID_OUTPUT_REPORT)
return -EINVAL;

if (count > ihid->bufsize)
count = ihid->bufsize;
/* +2 bytes to include the size of the reply in the query buffer */
ask_count = min(count + 2, (size_t)ihid->bufsize);

ret = i2c_hid_get_report(client,
report_type == HID_FEATURE_REPORT ? 0x03 : 0x01,
report_number, ihid->inbuf, count);
report_number, ihid->inbuf, ask_count);

if (ret < 0)
return ret;

count = ihid->inbuf[0] | (ihid->inbuf[1] << 8);
ret_count = ihid->inbuf[0] | (ihid->inbuf[1] << 8);

if (!ret_count)
return 0;

ret_count = min(ret_count, ask_count);

/* The query buffer contains the size, dropping it in the reply */
count = min(count, ret_count - 2);
memcpy(buf, ihid->inbuf + 2, count);

return count;
Expand Down

0 comments on commit e5b50fe

Please sign in to comment.