Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'hid-for-linus-2026031701' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid

Pull HID fixes from Jiri Kosina:

- various fixes dealing with (intentionally) broken devices in HID
core, logitech-hidpp and multitouch drivers (Lee Jones)

- fix for OOB in wacom driver (Benoît Sevens)

- fix for potentialy HID-bpf-induced buffer overflow in () (Benjamin
Tissoires)

- various other small fixes and device ID / quirk additions

* tag 'hid-for-linus-2026031701' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
HID: multitouch: Check to ensure report responses match the request
HID: logitech-hidpp: Prevent use-after-free on force feedback initialisation failure
HID: bpf: prevent buffer overflow in hid_hw_request
selftests/hid: fix compilation when bpf_wq and hid_device are not exported
HID: core: Mitigate potential OOB by removing bogus memset()
HID: intel-thc-hid: Set HID_PHYS with PCI BDF
HID: appletb-kbd: add .resume method in PM
HID: logitech-hidpp: Enable MX Master 4 over bluetooth
HID: input: Add HID_BATTERY_QUIRK_DYNAMIC for Elan touchscreens
HID: input: Drop Asus UX550* touchscreen ignore battery quirks
HID: asus: add xg mobile 2022 external hardware support
HID: wacom: fix out-of-bounds read in wacom_intuos_bt_irq

+61 -15
+2
drivers/hid/bpf/hid_bpf_dispatch.c
··· 444 444 (u64)(long)ctx, 445 445 true); /* prevent infinite recursions */ 446 446 447 + if (ret > size) 448 + ret = size; 447 449 if (ret > 0) 448 450 memcpy(buf, dma_data, ret); 449 451
+3 -2
drivers/hid/hid-appletb-kbd.c
··· 476 476 return 0; 477 477 } 478 478 479 - static int appletb_kbd_reset_resume(struct hid_device *hdev) 479 + static int appletb_kbd_resume(struct hid_device *hdev) 480 480 { 481 481 struct appletb_kbd *kbd = hid_get_drvdata(hdev); 482 482 ··· 500 500 .event = appletb_kbd_hid_event, 501 501 .input_configured = appletb_kbd_input_configured, 502 502 .suspend = pm_ptr(appletb_kbd_suspend), 503 - .reset_resume = pm_ptr(appletb_kbd_reset_resume), 503 + .resume = pm_ptr(appletb_kbd_resume), 504 + .reset_resume = pm_ptr(appletb_kbd_resume), 504 505 .driver.dev_groups = appletb_kbd_groups, 505 506 }; 506 507 module_hid_driver(appletb_kbd_hid_driver);
+3
drivers/hid/hid-asus.c
··· 1498 1498 USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X), 1499 1499 QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD }, 1500 1500 { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, 1501 + USB_DEVICE_ID_ASUSTEK_XGM_2022), 1502 + }, 1503 + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, 1501 1504 USB_DEVICE_ID_ASUSTEK_XGM_2023), 1502 1505 }, 1503 1506 { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
+4 -3
drivers/hid/hid-core.c
··· 2057 2057 rsize = max_buffer_size; 2058 2058 2059 2059 if (csize < rsize) { 2060 - dbg_hid("report %d is too short, (%d < %d)\n", report->id, 2061 - csize, rsize); 2062 - memset(cdata + csize, 0, rsize - csize); 2060 + hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %d)\n", 2061 + report->id, rsize, csize); 2062 + ret = -EINVAL; 2063 + goto out; 2063 2064 } 2064 2065 2065 2066 if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
+1 -2
drivers/hid/hid-ids.h
··· 229 229 #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X 0x1b4c 230 230 #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b 231 231 #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869 232 + #define USB_DEVICE_ID_ASUSTEK_XGM_2022 0x1970 232 233 #define USB_DEVICE_ID_ASUSTEK_XGM_2023 0x1a9a 233 234 234 235 #define USB_VENDOR_ID_ATEN 0x0557 ··· 455 454 #define USB_DEVICE_ID_TOSHIBA_CLICK_L9W 0x0401 456 455 #define USB_DEVICE_ID_HP_X2 0x074d 457 456 #define USB_DEVICE_ID_HP_X2_10_COVER 0x0755 458 - #define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544 459 - #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 460 457 #define I2C_DEVICE_ID_CHROMEBOOK_TROGDOR_POMPOM 0x2F81 461 458 462 459 #define USB_VENDOR_ID_ELECOM 0x056e
+11 -7
drivers/hid/hid-input.c
··· 354 354 #define HID_BATTERY_QUIRK_FEATURE (1 << 1) /* ask for feature report */ 355 355 #define HID_BATTERY_QUIRK_IGNORE (1 << 2) /* completely ignore the battery */ 356 356 #define HID_BATTERY_QUIRK_AVOID_QUERY (1 << 3) /* do not query the battery */ 357 + #define HID_BATTERY_QUIRK_DYNAMIC (1 << 4) /* report present only after life signs */ 357 358 358 359 static const struct hid_device_id hid_battery_quirks[] = { 359 360 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, ··· 387 386 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 388 387 USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD), 389 388 HID_BATTERY_QUIRK_IGNORE }, 390 - { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN), 391 - HID_BATTERY_QUIRK_IGNORE }, 392 - { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN), 393 - HID_BATTERY_QUIRK_IGNORE }, 394 389 { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L), 395 390 HID_BATTERY_QUIRK_AVOID_QUERY }, 396 391 { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_MW), ··· 399 402 * Elan HID touchscreens seem to all report a non present battery, 400 403 * set HID_BATTERY_QUIRK_IGNORE for all Elan I2C and USB HID devices. 401 404 */ 402 - { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_IGNORE }, 403 - { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_IGNORE }, 405 + { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_DYNAMIC }, 406 + { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_DYNAMIC }, 404 407 {} 405 408 }; 406 409 ··· 457 460 int ret = 0; 458 461 459 462 switch (prop) { 460 - case POWER_SUPPLY_PROP_PRESENT: 461 463 case POWER_SUPPLY_PROP_ONLINE: 462 464 val->intval = 1; 465 + break; 466 + 467 + case POWER_SUPPLY_PROP_PRESENT: 468 + val->intval = dev->battery_present; 463 469 break; 464 470 465 471 case POWER_SUPPLY_PROP_CAPACITY: ··· 577 577 if (quirks & HID_BATTERY_QUIRK_AVOID_QUERY) 578 578 dev->battery_avoid_query = true; 579 579 580 + dev->battery_present = (quirks & HID_BATTERY_QUIRK_DYNAMIC) ? false : true; 581 + 580 582 dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg); 581 583 if (IS_ERR(dev->battery)) { 582 584 error = PTR_ERR(dev->battery); ··· 634 632 return; 635 633 636 634 if (hidinput_update_battery_charge_status(dev, usage, value)) { 635 + dev->battery_present = true; 637 636 power_supply_changed(dev->battery); 638 637 return; 639 638 } ··· 650 647 if (dev->battery_status != HID_BATTERY_REPORTED || 651 648 capacity != dev->battery_capacity || 652 649 ktime_after(ktime_get_coarse(), dev->battery_ratelimit_time)) { 650 + dev->battery_present = true; 653 651 dev->battery_capacity = capacity; 654 652 dev->battery_status = HID_BATTERY_REPORTED; 655 653 dev->battery_ratelimit_time =
+5 -1
drivers/hid/hid-logitech-hidpp.c
··· 4487 4487 if (!ret) 4488 4488 ret = hidpp_ff_init(hidpp, &data); 4489 4489 4490 - if (ret) 4490 + if (ret) { 4491 4491 hid_warn(hidpp->hid_dev, 4492 4492 "Unable to initialize force feedback support, errno %d\n", 4493 4493 ret); 4494 + ret = 0; 4495 + } 4494 4496 } 4495 4497 4496 4498 /* ··· 4670 4668 HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb038) }, 4671 4669 { /* Slim Solar+ K980 Keyboard over Bluetooth */ 4672 4670 HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb391) }, 4671 + { /* MX Master 4 mouse over Bluetooth */ 4672 + HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb042) }, 4673 4673 {} 4674 4674 }; 4675 4675
+7
drivers/hid/hid-multitouch.c
··· 526 526 dev_warn(&hdev->dev, "failed to fetch feature %d\n", 527 527 report->id); 528 528 } else { 529 + /* The report ID in the request and the response should match */ 530 + if (report->id != buf[0]) { 531 + hid_err(hdev, "Returned feature report did not match the request\n"); 532 + goto free; 533 + } 534 + 529 535 ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf, 530 536 size, 0); 531 537 if (ret) 532 538 dev_warn(&hdev->dev, "failed to report feature\n"); 533 539 } 534 540 541 + free: 535 542 kfree(buf); 536 543 } 537 544
+1
drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-hid.c
··· 127 127 hid->product = le16_to_cpu(qcdev->dev_desc.product_id); 128 128 snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "quicki2c-hid", 129 129 hid->vendor, hid->product); 130 + strscpy(hid->phys, dev_name(qcdev->dev), sizeof(hid->phys)); 130 131 131 132 ret = hid_add_device(hid); 132 133 if (ret) {
+1
drivers/hid/intel-thc-hid/intel-quickspi/quickspi-hid.c
··· 118 118 hid->product = le16_to_cpu(qsdev->dev_desc.product_id); 119 119 snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "quickspi-hid", 120 120 hid->vendor, hid->product); 121 + strscpy(hid->phys, dev_name(qsdev->dev), sizeof(hid->phys)); 121 122 122 123 ret = hid_add_device(hid); 123 124 if (ret) {
+10
drivers/hid/wacom_wac.c
··· 1208 1208 1209 1209 switch (data[0]) { 1210 1210 case 0x04: 1211 + if (len < 32) { 1212 + dev_warn(wacom->pen_input->dev.parent, 1213 + "Report 0x04 too short: %zu bytes\n", len); 1214 + break; 1215 + } 1211 1216 wacom_intuos_bt_process_data(wacom, data + i); 1212 1217 i += 10; 1213 1218 fallthrough; 1214 1219 case 0x03: 1220 + if (i == 1 && len < 22) { 1221 + dev_warn(wacom->pen_input->dev.parent, 1222 + "Report 0x03 too short: %zu bytes\n", len); 1223 + break; 1224 + } 1215 1225 wacom_intuos_bt_process_data(wacom, data + i); 1216 1226 i += 10; 1217 1227 wacom_intuos_bt_process_data(wacom, data + i);
+1
include/linux/hid.h
··· 682 682 __s32 battery_charge_status; 683 683 enum hid_battery_status battery_status; 684 684 bool battery_avoid_query; 685 + bool battery_present; 685 686 ktime_t battery_ratelimit_time; 686 687 #endif 687 688
+12
tools/testing/selftests/hid/progs/hid_bpf_helpers.h
··· 6 6 #define __HID_BPF_HELPERS_H 7 7 8 8 /* "undefine" structs and enums in vmlinux.h, because we "override" them below */ 9 + #define bpf_wq bpf_wq___not_used 9 10 #define hid_bpf_ctx hid_bpf_ctx___not_used 10 11 #define hid_bpf_ops hid_bpf_ops___not_used 12 + #define hid_device hid_device___not_used 11 13 #define hid_report_type hid_report_type___not_used 12 14 #define hid_class_request hid_class_request___not_used 13 15 #define hid_bpf_attach_flags hid_bpf_attach_flags___not_used ··· 29 27 30 28 #include "vmlinux.h" 31 29 30 + #undef bpf_wq 32 31 #undef hid_bpf_ctx 33 32 #undef hid_bpf_ops 33 + #undef hid_device 34 34 #undef hid_report_type 35 35 #undef hid_class_request 36 36 #undef hid_bpf_attach_flags ··· 57 53 HID_FEATURE_REPORT = 2, 58 54 59 55 HID_REPORT_TYPES, 56 + }; 57 + 58 + struct hid_device { 59 + unsigned int id; 60 + } __attribute__((preserve_access_index)); 61 + 62 + struct bpf_wq { 63 + __u64 __opaque[2]; 60 64 }; 61 65 62 66 struct hid_bpf_ctx {