Re: [PATCH] HID: core: Reject report fields with a size or count of 0

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Jul 19 2025, Benjamin Tissoires wrote:
> On Jul 17 2025, Alan Stern wrote:
> > Testing by the syzbot fuzzer showed that the HID core gets a
> > shift-out-of-bounds exception when it tries to convert a 32-bit
> > quantity to a 0-bit quantity.  This is hardly an unexpected result,
> > but it means that we should not accept report fields that have a size
> > of zero bits.  Similarly, there's no reason to accept report fields
> > with a count of zero; either type of item is completely meaningless
> > since no information can be conveyed in zero bits.
> > 
> > Reject fields with a size or count of zero, and reject reports
> > containing such fields.
> > 
> > Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
> > Reported-by: syzbot+b63d677d63bcac06cf90@xxxxxxxxxxxxxxxxxxxxxxxxx
> > Closes: https://lore.kernel.org/linux-usb/68753a08.050a0220.33d347.0008.GAE@xxxxxxxxxx/
> > Tested-by: syzbot+b63d677d63bcac06cf90@xxxxxxxxxxxxxxxxxxxxxxxxx
> > Fixes: dde5845a529f ("[PATCH] Generic HID layer - code split")
> > Cc: stable@xxxxxxxxxxxxxxx
> > 
> > ---
> > 
> > The commit listed in the Fixes tag is not really the right one.  But
> > code motion made tracking it back any further more difficult than I
> > wanted to deal with, so I stopped there.  That commit is from 2006,
> > which is already far enough in the past.
> > 
> >  drivers/hid/hid-core.c |   15 ++++++++++++---
> >  1 file changed, 12 insertions(+), 3 deletions(-)
> > 
> > Index: usb-devel/drivers/hid/hid-core.c
> > ===================================================================
> > --- usb-devel.orig/drivers/hid/hid-core.c
> > +++ usb-devel/drivers/hid/hid-core.c
> > @@ -313,7 +313,14 @@ static int hid_add_field(struct hid_pars
> >  	}
> >  
> >  	offset = report->size;
> > -	report->size += parser->global.report_size * parser->global.report_count;
> > +	i = parser->global.report_size * parser->global.report_count;
> > +	if (i == 0) {
> > +		dbg_hid("invalid field size/count 0x%x 0x%x\n",
> > +			parser->global.report_size,
> > +			parser->global.report_count);
> > +		return -1;
> > +	}
> > +	report->size += i;
> >  
> >  	if (parser->device->ll_driver->max_buffer_size)
> >  		max_buffer_size = parser->device->ll_driver->max_buffer_size;
> > @@ -464,7 +471,8 @@ static int hid_parser_global(struct hid_
> >  
> >  	case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
> >  		parser->global.report_size = item_udata(item);
> > -		if (parser->global.report_size > 256) {
> > +		if (parser->global.report_size > 256 ||
> > +				parser->global.report_size == 0) {
> >  			hid_err(parser->device, "invalid report_size %d\n",
> >  					parser->global.report_size);
> >  			return -1;
> 
> Sigh... I applied this one too quickly before going on holidays.
> 
> This breaks the hid testsuite:
> https://gitlab.freedesktop.org/bentiss/hid/-/jobs/80805946
> 
> (yes, I should have run it before applying).
> 
> So basically, there are devices out there with a "broken" report size of
> 0, and this patch now entirely disables them.
> 
> That Saitek gamepad has the following (see tools/testing/selftests/hid/tests/test_gamepad.py):
>         0x95, 0x01,                    # ..Report Count (1)                  60
>         0x75, 0x00,                    # ..Report Size (0)                   62
>         0x81, 0x03,                    # ..Input (Cnst,Var,Abs)              64
> 
> So we'd need to disable the field, but not invalidate the entire report.
> 
> I'm glad I scheduled this one for the next cycle.
> 
> I'll try to get something next week.
> 

In case you are interested in fixing this, a quick reproducer can be
done through virtme-ng:

$> vng --verbose --kconfig --skip-module --config tools/testing/selftests/hid/config
$> make -j8
$> vng -v --user root --exec "mount bpffs -t bpf /sys/fs/bpf ; pytest ./tools/testing/selftests/hid/tests/test_gamepad.py -v -x --color=yes -k Saitek"

Cheers,
Benjamin




[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux