mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-23 07:23:12 +02:00
hid-for-linus-2025071501
-----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEoEVH9lhNrxiMPSyI7MXwXhnZSjYFAmh2cUgTHGJlbnRpc3NA a2VybmVsLm9yZwAKCRDsxfBeGdlKNlM+D/9krPRboz0p6ArZSQ6B4F8KOyo9hRZ9 q/ofrGwARPy0mrACU42wEqsD53/7L1yz0sj8WMFftdjMk3eT/zHupzB9LOFwUXGm c4CTTSGJrttx0n9uVaM9BADuIeP+hJnFJNgb3u170U6uX2NbUj+axNfwUHl/HZRm oVyZxBKEx/an2T3aL8cJabCyZcB3c7QfKdwKWjvUNC5cz6Ke6OmFy6Uo5U8FSgnL z6LJTlvW7Eq+z8ayfhX+uMraQgcQR5BU3LIEtnrDW+O5Mzr9iY+Ln5LfzYMhGALO 6DpiCf8uSvUp80kdPxkTjkyM4DTYfpnaJmetrMXRyoX73s0k8FO4F+QFMwao4gvR mlOk8Q6nltxemsNSVRYSiY7JNP1E7ECBOGBKjzhxllHCmX3KElvw8xiBMdv6KNBD UEs0TGMBirZ0e715piFBMJAlX7UNUWrduRnFualJLS0I+xacnn5xcI7XMGVdOUKt qr1WGb8iP4xvnPTF3tX4AHPPQ/jjxxo3ZExktCr7U42tL+R/7OujKENLHP5Y27ur KQXfxG4aSYA3m0pWIA98VVizTqUupqvdOjV104gx457sIZMML1JKY79hagamWFrO 1LGV2FAD484YOILwRHo453KmvRJX4tP0j2BaI8cvHCgvBGMjopIe2vHo3jCGDjue GC7rYihZt7HbfA== =PzWA -----END PGP SIGNATURE----- Merge tag 'hid-for-linus-2025071501' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid Pull HID fixes from Benjamin Tissoires: - one warning cleanup introduced in the last PR (Andy Shevchenko) - a nasty syzbot buffer underflow fix co-debugged with Alan Stern (Benjamin Tissoires) * tag 'hid-for-linus-2025071501' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: selftests/hid: add a test case for the recent syzbot underflow HID: core: do not bypass hid_hw_raw_request HID: core: ensure __hid_request reserves the report ID as the first byte HID: core: ensure the allocated report buffer can contain the reserved report ID HID: debug: Remove duplicate entry (BTN_WHEEL)
This commit is contained in:
commit
e003ef2cb1
|
@ -1883,9 +1883,12 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags)
|
||||||
/*
|
/*
|
||||||
* 7 extra bytes are necessary to achieve proper functionality
|
* 7 extra bytes are necessary to achieve proper functionality
|
||||||
* of implement() working on 8 byte chunks
|
* of implement() working on 8 byte chunks
|
||||||
|
* 1 extra byte for the report ID if it is null (not used) so
|
||||||
|
* we can reserve that extra byte in the first position of the buffer
|
||||||
|
* when sending it to .raw_request()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
u32 len = hid_report_len(report) + 7;
|
u32 len = hid_report_len(report) + 7 + (report->id == 0);
|
||||||
|
|
||||||
return kzalloc(len, flags);
|
return kzalloc(len, flags);
|
||||||
}
|
}
|
||||||
|
@ -1973,7 +1976,7 @@ static struct hid_report *hid_get_report(struct hid_report_enum *report_enum,
|
||||||
int __hid_request(struct hid_device *hid, struct hid_report *report,
|
int __hid_request(struct hid_device *hid, struct hid_report *report,
|
||||||
enum hid_class_request reqtype)
|
enum hid_class_request reqtype)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf, *data_buf;
|
||||||
int ret;
|
int ret;
|
||||||
u32 len;
|
u32 len;
|
||||||
|
|
||||||
|
@ -1981,13 +1984,19 @@ int __hid_request(struct hid_device *hid, struct hid_report *report,
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
data_buf = buf;
|
||||||
len = hid_report_len(report);
|
len = hid_report_len(report);
|
||||||
|
|
||||||
if (reqtype == HID_REQ_SET_REPORT)
|
if (report->id == 0) {
|
||||||
hid_output_report(report, buf);
|
/* reserve the first byte for the report ID */
|
||||||
|
data_buf++;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
ret = hid->ll_driver->raw_request(hid, report->id, buf, len,
|
if (reqtype == HID_REQ_SET_REPORT)
|
||||||
report->type, reqtype);
|
hid_output_report(report, data_buf);
|
||||||
|
|
||||||
|
ret = hid_hw_raw_request(hid, report->id, buf, len, report->type, reqtype);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dbg_hid("unable to complete request: %d\n", ret);
|
dbg_hid("unable to complete request: %d\n", ret);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -3299,7 +3299,7 @@ static const char *keys[KEY_MAX + 1] = {
|
||||||
[BTN_STYLUS2] = "Stylus2", [BTN_TOOL_DOUBLETAP] = "ToolDoubleTap",
|
[BTN_STYLUS2] = "Stylus2", [BTN_TOOL_DOUBLETAP] = "ToolDoubleTap",
|
||||||
[BTN_TOOL_TRIPLETAP] = "ToolTripleTap", [BTN_TOOL_QUADTAP] = "ToolQuadrupleTap",
|
[BTN_TOOL_TRIPLETAP] = "ToolTripleTap", [BTN_TOOL_QUADTAP] = "ToolQuadrupleTap",
|
||||||
[BTN_GEAR_DOWN] = "BtnGearDown", [BTN_GEAR_UP] = "BtnGearUp",
|
[BTN_GEAR_DOWN] = "BtnGearDown", [BTN_GEAR_UP] = "BtnGearUp",
|
||||||
[BTN_WHEEL] = "BtnWheel", [KEY_OK] = "Ok",
|
[KEY_OK] = "Ok",
|
||||||
[KEY_SELECT] = "Select", [KEY_GOTO] = "Goto",
|
[KEY_SELECT] = "Select", [KEY_GOTO] = "Goto",
|
||||||
[KEY_CLEAR] = "Clear", [KEY_POWER2] = "Power2",
|
[KEY_CLEAR] = "Clear", [KEY_POWER2] = "Power2",
|
||||||
[KEY_OPTION] = "Option", [KEY_INFO] = "Info",
|
[KEY_OPTION] = "Option", [KEY_INFO] = "Info",
|
||||||
|
|
|
@ -439,6 +439,68 @@ class BadResolutionMultiplierMouse(ResolutionMultiplierMouse):
|
||||||
return 32 # EPIPE
|
return 32 # EPIPE
|
||||||
|
|
||||||
|
|
||||||
|
class BadReportDescriptorMouse(BaseMouse):
|
||||||
|
"""
|
||||||
|
This "device" was one autogenerated by syzbot. There are a lot of issues in
|
||||||
|
it, and the most problematic is that it declares features that have no
|
||||||
|
size.
|
||||||
|
|
||||||
|
This leads to report->size being set to 0 and can mess up with usbhid
|
||||||
|
internals. Fortunately, uhid merely passes the incoming buffer, without
|
||||||
|
touching it so a buffer of size 0 will be translated to [] without
|
||||||
|
triggering a kernel oops.
|
||||||
|
|
||||||
|
Because the report descriptor is wrong, no input are created, and we need
|
||||||
|
to tweak a little bit the parameters to make it look correct.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
report_descriptor = [
|
||||||
|
0x96, 0x01, 0x00, # Report Count (1) 0
|
||||||
|
0x06, 0x01, 0x00, # Usage Page (Generic Desktop) 3
|
||||||
|
# 0x03, 0x00, 0x00, 0x00, 0x00, # Ignored by the kernel somehow
|
||||||
|
0x2a, 0x90, 0xa0, # Usage Maximum (41104) 6
|
||||||
|
0x27, 0x00, 0x00, 0x00, 0x00, # Logical Maximum (0) 9
|
||||||
|
0xb3, 0x81, 0x3e, 0x25, 0x03, # Feature (Cnst,Arr,Abs,Vol) 14
|
||||||
|
0x1b, 0xdd, 0xe8, 0x40, 0x50, # Usage Minimum (1346431197) 19
|
||||||
|
0x3b, 0x5d, 0x8c, 0x3d, 0xda, # Designator Index 24
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, rdesc=report_descriptor, name=None, input_info=(3, 0x045E, 0x07DA)
|
||||||
|
):
|
||||||
|
super().__init__(rdesc, name, input_info)
|
||||||
|
self.high_resolution_report_called = False
|
||||||
|
|
||||||
|
def get_evdev(self, application=None):
|
||||||
|
assert self._input_nodes is None
|
||||||
|
return (
|
||||||
|
"Ok" # should be a list or None, but both would fail, so abusing the system
|
||||||
|
)
|
||||||
|
|
||||||
|
def next_sync_events(self, application=None):
|
||||||
|
# there are no evdev nodes, so no events
|
||||||
|
return []
|
||||||
|
|
||||||
|
def is_ready(self):
|
||||||
|
# we wait for the SET_REPORT command to come
|
||||||
|
return self.high_resolution_report_called
|
||||||
|
|
||||||
|
def set_report(self, req, rnum, rtype, data):
|
||||||
|
if rtype != self.UHID_FEATURE_REPORT:
|
||||||
|
raise InvalidHIDCommunication(f"Unexpected report type: {rtype}")
|
||||||
|
if rnum != 0x0:
|
||||||
|
raise InvalidHIDCommunication(f"Unexpected report number: {rnum}")
|
||||||
|
|
||||||
|
if len(data) != 1:
|
||||||
|
raise InvalidHIDCommunication(f"Unexpected data: {data}, expected '[0]'")
|
||||||
|
|
||||||
|
self.high_resolution_report_called = True
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
class ResolutionMultiplierHWheelMouse(TwoWheelMouse):
|
class ResolutionMultiplierHWheelMouse(TwoWheelMouse):
|
||||||
# fmt: off
|
# fmt: off
|
||||||
report_descriptor = [
|
report_descriptor = [
|
||||||
|
@ -975,3 +1037,11 @@ class TestMiMouse(TestWheelMouse):
|
||||||
# assert below print out the real error
|
# assert below print out the real error
|
||||||
pass
|
pass
|
||||||
assert remaining == []
|
assert remaining == []
|
||||||
|
|
||||||
|
|
||||||
|
class TestBadReportDescriptorMouse(base.BaseTestCase.TestUhid):
|
||||||
|
def create_device(self):
|
||||||
|
return BadReportDescriptorMouse()
|
||||||
|
|
||||||
|
def assertName(self, uhdev):
|
||||||
|
pass
|
||||||
|
|
Loading…
Reference in New Issue
Block a user