Re: [PATCH] HID: sensor-hub: fix out-of-bounds access in sensor_hub_get_feature()
[email protected] Wed, 05 Aug 2026 16:51:22 +0000
| Newsgroups | org.kernel.vger.linux-input |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: Pre-existing issues: - [High] The introduced bounds check allows reading adjacent independent items into a single item's buffer space when `report_size > 32`. - [High] Byte-wise `memcpy` from native-endian `s32` array copies padding bytes on Big-Endian architectures for fields smaller than 32 bits. - [High] Fields smaller than 8 bits are silently dropped due to integer division by 8. -- --- Patch [1]: [PATCH] HID: sensor-hub: fix out-of-bounds access in sensor_hub_get_feature() --- commit b3260de30fa032d167e378c546af0b283ff6ce04 Author: Shengzhuo Wei <[email protected]> HID: sensor-hub: fix out-of-bounds access in sensor_hub_get_feature() This commit addresses an out-of-bounds access issue in sensor_hub_get_feature() by bounding the per-iteration copy size. It restricts the copy size to the minimum of the report size, remaining source buffer, and remaining destination buffer. > diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c > index 90666ff629def..7e97ca98a3883 100644 > --- a/drivers/hid/hid-sensor-hub.c > +++ b/drivers/hid/hid-sensor-hub.c > @@ -270,11 +270,18 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, > > val_ptr = (u8 *)report->field[field_index]->value; > for (i = 0; i < report->field[field_index]->report_count; ++i) { > + int copy = report->field[field_index]->report_size / 8; [Severity: High] This is a pre-existing issue, but does this silently drop fields smaller than 8 bits? When sensor_hub_get_feature() is called for a sub-byte field (like a 4-bit flag), the integer division by 8 evaluates to 0. This causes memcpy to copy 0 bytes, leaving the caller's buffer unpopulated even though the HID core correctly parsed the value into the field->value array. > + int src_remaining = (report->field[field_index]->report_count - i) * > + sizeof(__s32); > + > if (buffer_index >= ret) > break; > > - memcpy(&((u8 *)buffer)[buffer_index], val_ptr, > - report->field[field_index]->report_size / 8); > + if (copy > src_remaining) > + copy = src_remaining; [Severity: High] This isn't a bug introduced by this patch, but does this bounds check still allow reading adjacent independent items into a single item's buffer space? The HID core truncates and stores each field item in a single 4-byte __s32 element. By bounding the copy size to src_remaining (the remaining size of the entire field->value array) instead of a single element (sizeof(__s32)), if the report size is greater than 32 bits, the copy size will exceed 4 bytes. Could this cause memcpy to incorrectly read the next independent value element from the array and append it to the current item? > + if (copy > buffer_size - buffer_index) > + copy = buffer_size - buffer_index; > + memcpy(&((u8 *)buffer)[buffer_index], val_ptr, copy); [Severity: High] This is a pre-existing issue, but does this byte-wise memcpy from a native-endian s32 array copy padding bytes on big-endian architectures for fields smaller than 32 bits? The function extracts fields that the HID core has parsed into native-endian 32-bit integers. For a 16-bit field on a big-endian system, the valid data resides at byte offsets 2 and 3, but memcpy copies from the lowest memory address. Could this result in returning zeroes by copying the most significant padding bytes instead of the actual data? > val_ptr += sizeof(__s32); > buffer_index += (report->field[field_index]->report_size / 8); > } -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=1