hid-for-linus-2026031701
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEL65usyKPHcrRDEicpmLzj2vtYEkFAmm5t3QACgkQpmLzj2vt YEk90hAArhy85Gy5uTQwdj5TVnGIwVH5+twiOz4S0If396duQGfK3MY+c+jzW2kO 7UI2uWV4tgXJGSoK1kTuQ3IXGgUDGofbaQ15nltpibQ4c+3whcDmMRICGIA/OqCk FmHHAV264Y5y6bapG7VvT8PLv0N+TtGV4G4LhQv90eObnRXXnc0m+H0s2IObr2py aBJgmgFQQ3DMWddX5DMatMd6M6e+2kJHY3X/41youvbvVJoWtqrJQEKIB19HDR8o 9GkEjn4GLMPZ6hPlTJCnkRn7zfRWQ3MvUMft1kCdVtpOlqvftHoBrXvP6X1YDtPR Hy07HkH1Jpq0zI6AYyKj7f36oasnnNCm4ZFijn2RBx2chmKEUrpz2fSJ4aS5YU81 QqhOjVR+euYL7kQ1UtoFGNwOhBHKWcJr5AezxxUNwn4SJ1bl8TGB63OEt2/1GI8/ L1PMMAgHnxUAlJui38PfeiXboUeS9bfPiJd20FnGzCghsdvk6a+W9oWz+2yhs+Fy csm1MvcxhZZ7ugXPmscE/U6iLueaqlj42dQ+wkm6sh8aYKS+9eIlIgNpu4Q9Z//e LZGPOjx+jDWiqqTBmXke7hGMXHNXHRbWDLWlE+Du4XS5sfKwTDRKXs+g3MWI/nVf gHvuHuKQvrQHiAcnWH0fNJbsHaGExpWWAbb+yoWCJHJAU3vj7ek= =1U5m -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
f0caa1d49c
|
|
@ -444,6 +444,8 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
|
|||
(u64)(long)ctx,
|
||||
true); /* prevent infinite recursions */
|
||||
|
||||
if (ret > size)
|
||||
ret = size;
|
||||
if (ret > 0)
|
||||
memcpy(buf, dma_data, ret);
|
||||
|
||||
|
|
|
|||
|
|
@ -476,7 +476,7 @@ static int appletb_kbd_suspend(struct hid_device *hdev, pm_message_t msg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int appletb_kbd_reset_resume(struct hid_device *hdev)
|
||||
static int appletb_kbd_resume(struct hid_device *hdev)
|
||||
{
|
||||
struct appletb_kbd *kbd = hid_get_drvdata(hdev);
|
||||
|
||||
|
|
@ -500,7 +500,8 @@ static struct hid_driver appletb_kbd_hid_driver = {
|
|||
.event = appletb_kbd_hid_event,
|
||||
.input_configured = appletb_kbd_input_configured,
|
||||
.suspend = pm_ptr(appletb_kbd_suspend),
|
||||
.reset_resume = pm_ptr(appletb_kbd_reset_resume),
|
||||
.resume = pm_ptr(appletb_kbd_resume),
|
||||
.reset_resume = pm_ptr(appletb_kbd_resume),
|
||||
.driver.dev_groups = appletb_kbd_groups,
|
||||
};
|
||||
module_hid_driver(appletb_kbd_hid_driver);
|
||||
|
|
|
|||
|
|
@ -1497,6 +1497,9 @@ static const struct hid_device_id asus_devices[] = {
|
|||
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
|
||||
USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X),
|
||||
QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
|
||||
USB_DEVICE_ID_ASUSTEK_XGM_2022),
|
||||
},
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
|
||||
USB_DEVICE_ID_ASUSTEK_XGM_2023),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2057,9 +2057,10 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *
|
|||
rsize = max_buffer_size;
|
||||
|
||||
if (csize < rsize) {
|
||||
dbg_hid("report %d is too short, (%d < %d)\n", report->id,
|
||||
csize, rsize);
|
||||
memset(cdata + csize, 0, rsize - csize);
|
||||
hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %d)\n",
|
||||
report->id, rsize, csize);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
|
||||
|
|
|
|||
|
|
@ -229,6 +229,7 @@
|
|||
#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X 0x1b4c
|
||||
#define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b
|
||||
#define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869
|
||||
#define USB_DEVICE_ID_ASUSTEK_XGM_2022 0x1970
|
||||
#define USB_DEVICE_ID_ASUSTEK_XGM_2023 0x1a9a
|
||||
|
||||
#define USB_VENDOR_ID_ATEN 0x0557
|
||||
|
|
@ -454,8 +455,6 @@
|
|||
#define USB_DEVICE_ID_TOSHIBA_CLICK_L9W 0x0401
|
||||
#define USB_DEVICE_ID_HP_X2 0x074d
|
||||
#define USB_DEVICE_ID_HP_X2_10_COVER 0x0755
|
||||
#define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544
|
||||
#define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706
|
||||
#define I2C_DEVICE_ID_CHROMEBOOK_TROGDOR_POMPOM 0x2F81
|
||||
|
||||
#define USB_VENDOR_ID_ELECOM 0x056e
|
||||
|
|
|
|||
|
|
@ -354,6 +354,7 @@ static enum power_supply_property hidinput_battery_props[] = {
|
|||
#define HID_BATTERY_QUIRK_FEATURE (1 << 1) /* ask for feature report */
|
||||
#define HID_BATTERY_QUIRK_IGNORE (1 << 2) /* completely ignore the battery */
|
||||
#define HID_BATTERY_QUIRK_AVOID_QUERY (1 << 3) /* do not query the battery */
|
||||
#define HID_BATTERY_QUIRK_DYNAMIC (1 << 4) /* report present only after life signs */
|
||||
|
||||
static const struct hid_device_id hid_battery_quirks[] = {
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
|
||||
|
|
@ -386,10 +387,6 @@ static const struct hid_device_id hid_battery_quirks[] = {
|
|||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
|
||||
USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
|
||||
HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L),
|
||||
HID_BATTERY_QUIRK_AVOID_QUERY },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_MW),
|
||||
|
|
@ -402,8 +399,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
|
|||
* Elan HID touchscreens seem to all report a non present battery,
|
||||
* set HID_BATTERY_QUIRK_IGNORE for all Elan I2C and USB HID devices.
|
||||
*/
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_IGNORE },
|
||||
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_DYNAMIC },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_DYNAMIC },
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
@ -460,11 +457,14 @@ static int hidinput_get_battery_property(struct power_supply *psy,
|
|||
int ret = 0;
|
||||
|
||||
switch (prop) {
|
||||
case POWER_SUPPLY_PROP_PRESENT:
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
val->intval = 1;
|
||||
break;
|
||||
|
||||
case POWER_SUPPLY_PROP_PRESENT:
|
||||
val->intval = dev->battery_present;
|
||||
break;
|
||||
|
||||
case POWER_SUPPLY_PROP_CAPACITY:
|
||||
if (dev->battery_status != HID_BATTERY_REPORTED &&
|
||||
!dev->battery_avoid_query) {
|
||||
|
|
@ -577,6 +577,8 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
|
|||
if (quirks & HID_BATTERY_QUIRK_AVOID_QUERY)
|
||||
dev->battery_avoid_query = true;
|
||||
|
||||
dev->battery_present = (quirks & HID_BATTERY_QUIRK_DYNAMIC) ? false : true;
|
||||
|
||||
dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg);
|
||||
if (IS_ERR(dev->battery)) {
|
||||
error = PTR_ERR(dev->battery);
|
||||
|
|
@ -632,6 +634,7 @@ static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
|
|||
return;
|
||||
|
||||
if (hidinput_update_battery_charge_status(dev, usage, value)) {
|
||||
dev->battery_present = true;
|
||||
power_supply_changed(dev->battery);
|
||||
return;
|
||||
}
|
||||
|
|
@ -647,6 +650,7 @@ static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
|
|||
if (dev->battery_status != HID_BATTERY_REPORTED ||
|
||||
capacity != dev->battery_capacity ||
|
||||
ktime_after(ktime_get_coarse(), dev->battery_ratelimit_time)) {
|
||||
dev->battery_present = true;
|
||||
dev->battery_capacity = capacity;
|
||||
dev->battery_status = HID_BATTERY_REPORTED;
|
||||
dev->battery_ratelimit_time =
|
||||
|
|
|
|||
|
|
@ -4487,10 +4487,12 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
if (!ret)
|
||||
ret = hidpp_ff_init(hidpp, &data);
|
||||
|
||||
if (ret)
|
||||
if (ret) {
|
||||
hid_warn(hidpp->hid_dev,
|
||||
"Unable to initialize force feedback support, errno %d\n",
|
||||
ret);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -4668,6 +4670,8 @@ static const struct hid_device_id hidpp_devices[] = {
|
|||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb038) },
|
||||
{ /* Slim Solar+ K980 Keyboard over Bluetooth */
|
||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb391) },
|
||||
{ /* MX Master 4 mouse over Bluetooth */
|
||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb042) },
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -526,12 +526,19 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
|
|||
dev_warn(&hdev->dev, "failed to fetch feature %d\n",
|
||||
report->id);
|
||||
} else {
|
||||
/* The report ID in the request and the response should match */
|
||||
if (report->id != buf[0]) {
|
||||
hid_err(hdev, "Returned feature report did not match the request\n");
|
||||
goto free;
|
||||
}
|
||||
|
||||
ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf,
|
||||
size, 0);
|
||||
if (ret)
|
||||
dev_warn(&hdev->dev, "failed to report feature\n");
|
||||
}
|
||||
|
||||
free:
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ int quicki2c_hid_probe(struct quicki2c_device *qcdev)
|
|||
hid->product = le16_to_cpu(qcdev->dev_desc.product_id);
|
||||
snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "quicki2c-hid",
|
||||
hid->vendor, hid->product);
|
||||
strscpy(hid->phys, dev_name(qcdev->dev), sizeof(hid->phys));
|
||||
|
||||
ret = hid_add_device(hid);
|
||||
if (ret) {
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ int quickspi_hid_probe(struct quickspi_device *qsdev)
|
|||
hid->product = le16_to_cpu(qsdev->dev_desc.product_id);
|
||||
snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "quickspi-hid",
|
||||
hid->vendor, hid->product);
|
||||
strscpy(hid->phys, dev_name(qsdev->dev), sizeof(hid->phys));
|
||||
|
||||
ret = hid_add_device(hid);
|
||||
if (ret) {
|
||||
|
|
|
|||
|
|
@ -1208,10 +1208,20 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)
|
|||
|
||||
switch (data[0]) {
|
||||
case 0x04:
|
||||
if (len < 32) {
|
||||
dev_warn(wacom->pen_input->dev.parent,
|
||||
"Report 0x04 too short: %zu bytes\n", len);
|
||||
break;
|
||||
}
|
||||
wacom_intuos_bt_process_data(wacom, data + i);
|
||||
i += 10;
|
||||
fallthrough;
|
||||
case 0x03:
|
||||
if (i == 1 && len < 22) {
|
||||
dev_warn(wacom->pen_input->dev.parent,
|
||||
"Report 0x03 too short: %zu bytes\n", len);
|
||||
break;
|
||||
}
|
||||
wacom_intuos_bt_process_data(wacom, data + i);
|
||||
i += 10;
|
||||
wacom_intuos_bt_process_data(wacom, data + i);
|
||||
|
|
|
|||
|
|
@ -682,6 +682,7 @@ struct hid_device {
|
|||
__s32 battery_charge_status;
|
||||
enum hid_battery_status battery_status;
|
||||
bool battery_avoid_query;
|
||||
bool battery_present;
|
||||
ktime_t battery_ratelimit_time;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@
|
|||
#define __HID_BPF_HELPERS_H
|
||||
|
||||
/* "undefine" structs and enums in vmlinux.h, because we "override" them below */
|
||||
#define bpf_wq bpf_wq___not_used
|
||||
#define hid_bpf_ctx hid_bpf_ctx___not_used
|
||||
#define hid_bpf_ops hid_bpf_ops___not_used
|
||||
#define hid_device hid_device___not_used
|
||||
#define hid_report_type hid_report_type___not_used
|
||||
#define hid_class_request hid_class_request___not_used
|
||||
#define hid_bpf_attach_flags hid_bpf_attach_flags___not_used
|
||||
|
|
@ -27,8 +29,10 @@
|
|||
|
||||
#include "vmlinux.h"
|
||||
|
||||
#undef bpf_wq
|
||||
#undef hid_bpf_ctx
|
||||
#undef hid_bpf_ops
|
||||
#undef hid_device
|
||||
#undef hid_report_type
|
||||
#undef hid_class_request
|
||||
#undef hid_bpf_attach_flags
|
||||
|
|
@ -55,6 +59,14 @@ enum hid_report_type {
|
|||
HID_REPORT_TYPES,
|
||||
};
|
||||
|
||||
struct hid_device {
|
||||
unsigned int id;
|
||||
} __attribute__((preserve_access_index));
|
||||
|
||||
struct bpf_wq {
|
||||
__u64 __opaque[2];
|
||||
};
|
||||
|
||||
struct hid_bpf_ctx {
|
||||
struct hid_device *hid;
|
||||
__u32 allocated_size;
|
||||
|
|
|
|||
Loading…
Reference in New Issue