Skip to content

Commit 634f498

Browse files
thejhgregkh
authored andcommitted
HID: core: fix number/pointer type confusion on long items
commit 28abce9 upstream. When fetch_item() is called by hid_scan_report() on an item with HID_ITEM_TAG_LONG, it stores a pointer to the item data in item->data.longdata instead of storing a value directly in item->data.{u8/u16/u32}. When item_udata() or item_sdata() encounters such an item, it incorrectly assumes that the item is in short format, and therefore returns the lower part of a kernel pointer reinterpreted as a number. When a HID device is connected whose descriptor contains a HID_GLOBAL_ITEM_TAG_REPORT_SIZE encoded in long format with size=4, this causes the lower half of a kernel pointer to be printed into dmesg as a number, like this: hid (null): invalid report_size 107953555 To fix it, let item_udata() and item_sdata() verify that the item is in short format. Note that this bug only affects hid_scan_report(), while the main parsing pass hid_parse_collections() will always bail out when encountering a long item. Sidenote: There are currently no users of data.longdata; maybe we should just remove any parsing of long-format descriptors as a follow-up. Fixes: 3dc8fc0 ("HID: Use hid_parser for pre-scanning the report descriptors") Cc: stable@vger.kernel.org Signed-off-by: Jann Horn <jannh@google.com> Signed-off-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 33ea29f commit 634f498

1 file changed

Lines changed: 6 additions & 0 deletions

File tree

drivers/hid/hid-core.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,9 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
349349

350350
static u32 item_udata(struct hid_item *item)
351351
{
352+
if (item->format != HID_ITEM_FORMAT_SHORT)
353+
return 0;
354+
352355
switch (item->size) {
353356
case 1: return item->data.u8;
354357
case 2: return item->data.u16;
@@ -359,6 +362,9 @@ static u32 item_udata(struct hid_item *item)
359362

360363
static s32 item_sdata(struct hid_item *item)
361364
{
365+
if (item->format != HID_ITEM_FORMAT_SHORT)
366+
return 0;
367+
362368
switch (item->size) {
363369
case 1: return item->data.s8;
364370
case 2: return item->data.s16;

0 commit comments

Comments
 (0)