@@ -439,6 +439,68 @@ def set_report(self, req, rnum, rtype, data):
439439 return 32 # EPIPE
440440
441441
442+ class BadReportDescriptorMouse (BaseMouse ):
443+ """
444+ This "device" was one autogenerated by syzbot. There are a lot of issues in
445+ it, and the most problematic is that it declares features that have no
446+ size.
447+
448+ This leads to report->size being set to 0 and can mess up with usbhid
449+ internals. Fortunately, uhid merely passes the incoming buffer, without
450+ touching it so a buffer of size 0 will be translated to [] without
451+ triggering a kernel oops.
452+
453+ Because the report descriptor is wrong, no input are created, and we need
454+ to tweak a little bit the parameters to make it look correct.
455+ """
456+
457+ # fmt: off
458+ report_descriptor = [
459+ 0x96 , 0x01 , 0x00 , # Report Count (1) 0
460+ 0x06 , 0x01 , 0x00 , # Usage Page (Generic Desktop) 3
461+ # 0x03, 0x00, 0x00, 0x00, 0x00, # Ignored by the kernel somehow
462+ 0x2a , 0x90 , 0xa0 , # Usage Maximum (41104) 6
463+ 0x27 , 0x00 , 0x00 , 0x00 , 0x00 , # Logical Maximum (0) 9
464+ 0xb3 , 0x81 , 0x3e , 0x25 , 0x03 , # Feature (Cnst,Arr,Abs,Vol) 14
465+ 0x1b , 0xdd , 0xe8 , 0x40 , 0x50 , # Usage Minimum (1346431197) 19
466+ 0x3b , 0x5d , 0x8c , 0x3d , 0xda , # Designator Index 24
467+ ]
468+ # fmt: on
469+
470+ def __init__ (
471+ self , rdesc = report_descriptor , name = None , input_info = (3 , 0x045E , 0x07DA )
472+ ):
473+ super ().__init__ (rdesc , name , input_info )
474+ self .high_resolution_report_called = False
475+
476+ def get_evdev (self , application = None ):
477+ assert self ._input_nodes is None
478+ return (
479+ "Ok" # should be a list or None, but both would fail, so abusing the system
480+ )
481+
482+ def next_sync_events (self , application = None ):
483+ # there are no evdev nodes, so no events
484+ return []
485+
486+ def is_ready (self ):
487+ # we wait for the SET_REPORT command to come
488+ return self .high_resolution_report_called
489+
490+ def set_report (self , req , rnum , rtype , data ):
491+ if rtype != self .UHID_FEATURE_REPORT :
492+ raise InvalidHIDCommunication (f"Unexpected report type: { rtype } " )
493+ if rnum != 0x0 :
494+ raise InvalidHIDCommunication (f"Unexpected report number: { rnum } " )
495+
496+ if len (data ) != 1 :
497+ raise InvalidHIDCommunication (f"Unexpected data: { data } , expected '[0]'" )
498+
499+ self .high_resolution_report_called = True
500+
501+ return 0
502+
503+
442504class ResolutionMultiplierHWheelMouse (TwoWheelMouse ):
443505 # fmt: off
444506 report_descriptor = [
@@ -975,3 +1037,11 @@ def assertInputEvents(self, expected_events, effective_events):
9751037 # assert below print out the real error
9761038 pass
9771039 assert remaining == []
1040+
1041+
1042+ class TestBadReportDescriptorMouse (base .BaseTestCase .TestUhid ):
1043+ def create_device (self ):
1044+ return BadReportDescriptorMouse ()
1045+
1046+ def assertName (self , uhdev ):
1047+ pass
0 commit comments