Skip to content

Commit 02d6eee

Browse files
committed
Merge tag 'hid-for-linus-2025082901' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID fixes from Jiri Kosina: - fixes for memory corruption in intel-thc-hid, hid-multitouch, hid-mcp2221 and hid-asus (Aaron Ma, Qasim Ijaz, Arnaud Lecomte) - power management/resume fix for intel-ish-hid (Zhang Lixu) - driver reinitialization fix for intel-thc-hid (Even Xu) - ensure that battery level status is reported as soon as possible, which is required at least for some Android use-cases (José Expósito) - quite a few new device ID additions and device-specific quirks * tag 'hid-for-linus-2025082901' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: HID: quirks: add support for Legion Go dual dinput modes HID: elecom: add support for ELECOM M-DT2DRBK HID: logitech: Add ids for G PRO 2 LIGHTSPEED HID: input: report battery status changes immediately HID: input: rename hidinput_set_battery_charge_status() HID: intel-thc-hid: Intel-quicki2c: Enhance driver re-install flow HID: hid-ntrig: fix unable to handle page fault in ntrig_report_version() HID: asus: fix UAF via HID_CLAIMED_INPUT validation hid: fix I2C read buffer overflow in raw_event() for mcp2221 HID: wacom: Add a new Art Pen 2 HID: multitouch: fix slab out-of-bounds access in mt_report_fixup() HID: Kconfig: Fix spelling mistake "enthropy" -> "entropy" HID: intel-ish-hid: Increase ISHTP resume ack timeout to 300ms HID: intel-thc-hid: intel-thc: Fix incorrect pointer arithmetic in I2C regs save HID: intel-thc-hid: intel-quicki2c: Fix ACPI dsd ICRS/ISUB length
2 parents ec1abfc + 1f3214a commit 02d6eee

File tree

20 files changed

+79
-42
lines changed

20 files changed

+79
-42
lines changed

drivers/hid/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,7 @@ config HID_U2FZERO
12431243

12441244
U2F Zero supports custom commands for blinking the LED
12451245
and getting data from the internal hardware RNG.
1246-
The internal hardware can be used to feed the enthropy pool.
1246+
The internal hardware can be used to feed the entropy pool.
12471247

12481248
U2F Zero only supports blinking its LED, so this driver doesn't
12491249
allow setting the brightness to anything but 1, which will

drivers/hid/hid-asus.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,13 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
12131213
return ret;
12141214
}
12151215

1216-
if (!drvdata->input) {
1216+
/*
1217+
* Check that input registration succeeded. Checking that
1218+
* HID_CLAIMED_INPUT is set prevents a UAF when all input devices
1219+
* were freed during registration due to no usages being mapped,
1220+
* leaving drvdata->input pointing to freed memory.
1221+
*/
1222+
if (!drvdata->input || !(hdev->claimed & HID_CLAIMED_INPUT)) {
12171223
hid_err(hdev, "Asus input not registered\n");
12181224
ret = -ENOMEM;
12191225
goto err_stop_hw;

drivers/hid/hid-elecom.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ static const __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
101101
*/
102102
mouse_button_fixup(hdev, rdesc, *rsize, 12, 30, 14, 20, 8);
103103
break;
104+
case USB_DEVICE_ID_ELECOM_M_DT2DRBK:
104105
case USB_DEVICE_ID_ELECOM_M_HT1DRBK_011C:
105106
/*
106107
* Report descriptor format:
@@ -123,6 +124,7 @@ static const struct hid_device_id elecom_devices[] = {
123124
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
124125
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
125126
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
127+
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT2DRBK) },
126128
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_010C) },
127129
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_019B) },
128130
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D) },

drivers/hid/hid-ids.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@
451451
#define USB_DEVICE_ID_ELECOM_M_XT4DRBK 0x00fd
452452
#define USB_DEVICE_ID_ELECOM_M_DT1URBK 0x00fe
453453
#define USB_DEVICE_ID_ELECOM_M_DT1DRBK 0x00ff
454+
#define USB_DEVICE_ID_ELECOM_M_DT2DRBK 0x018d
454455
#define USB_DEVICE_ID_ELECOM_M_HT1URBK_010C 0x010c
455456
#define USB_DEVICE_ID_ELECOM_M_HT1URBK_019B 0x019b
456457
#define USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D 0x010d
@@ -834,6 +835,8 @@
834835
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019
835836
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E 0x602e
836837
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093 0x6093
838+
#define USB_DEVICE_ID_LENOVO_LEGION_GO_DUAL_DINPUT 0x6184
839+
#define USB_DEVICE_ID_LENOVO_LEGION_GO2_DUAL_DINPUT 0x61ed
837840

838841
#define USB_VENDOR_ID_LETSKETCH 0x6161
839842
#define USB_DEVICE_ID_WP9620N 0x4d15
@@ -907,6 +910,7 @@
907910
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 0xc534
908911
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539
909912
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f
913+
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2 0xc543
910914
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a
911915
#define USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER 0xc548
912916
#define USB_DEVICE_ID_SPACETRAVELLER 0xc623

drivers/hid/hid-input-test.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,23 @@
77

88
#include <kunit/test.h>
99

10-
static void hid_test_input_set_battery_charge_status(struct kunit *test)
10+
static void hid_test_input_update_battery_charge_status(struct kunit *test)
1111
{
1212
struct hid_device *dev;
1313
bool handled;
1414

1515
dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
1616
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
1717

18-
handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0);
18+
handled = hidinput_update_battery_charge_status(dev, HID_DG_HEIGHT, 0);
1919
KUNIT_EXPECT_FALSE(test, handled);
2020
KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN);
2121

22-
handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0);
22+
handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 0);
2323
KUNIT_EXPECT_TRUE(test, handled);
2424
KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING);
2525

26-
handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1);
26+
handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 1);
2727
KUNIT_EXPECT_TRUE(test, handled);
2828
KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING);
2929
}
@@ -63,7 +63,7 @@ static void hid_test_input_get_battery_property(struct kunit *test)
6363
}
6464

6565
static struct kunit_case hid_input_tests[] = {
66-
KUNIT_CASE(hid_test_input_set_battery_charge_status),
66+
KUNIT_CASE(hid_test_input_update_battery_charge_status),
6767
KUNIT_CASE(hid_test_input_get_battery_property),
6868
{ }
6969
};

drivers/hid/hid-input.c

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -595,13 +595,33 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
595595
dev->battery = NULL;
596596
}
597597

598-
static void hidinput_update_battery(struct hid_device *dev, int value)
598+
static bool hidinput_update_battery_charge_status(struct hid_device *dev,
599+
unsigned int usage, int value)
600+
{
601+
switch (usage) {
602+
case HID_BAT_CHARGING:
603+
dev->battery_charge_status = value ?
604+
POWER_SUPPLY_STATUS_CHARGING :
605+
POWER_SUPPLY_STATUS_DISCHARGING;
606+
return true;
607+
}
608+
609+
return false;
610+
}
611+
612+
static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
613+
int value)
599614
{
600615
int capacity;
601616

602617
if (!dev->battery)
603618
return;
604619

620+
if (hidinput_update_battery_charge_status(dev, usage, value)) {
621+
power_supply_changed(dev->battery);
622+
return;
623+
}
624+
605625
if (value == 0 || value < dev->battery_min || value > dev->battery_max)
606626
return;
607627

@@ -617,20 +637,6 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
617637
power_supply_changed(dev->battery);
618638
}
619639
}
620-
621-
static bool hidinput_set_battery_charge_status(struct hid_device *dev,
622-
unsigned int usage, int value)
623-
{
624-
switch (usage) {
625-
case HID_BAT_CHARGING:
626-
dev->battery_charge_status = value ?
627-
POWER_SUPPLY_STATUS_CHARGING :
628-
POWER_SUPPLY_STATUS_DISCHARGING;
629-
return true;
630-
}
631-
632-
return false;
633-
}
634640
#else /* !CONFIG_HID_BATTERY_STRENGTH */
635641
static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
636642
struct hid_field *field, bool is_percentage)
@@ -642,14 +648,9 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
642648
{
643649
}
644650

645-
static void hidinput_update_battery(struct hid_device *dev, int value)
646-
{
647-
}
648-
649-
static bool hidinput_set_battery_charge_status(struct hid_device *dev,
650-
unsigned int usage, int value)
651+
static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
652+
int value)
651653
{
652-
return false;
653654
}
654655
#endif /* CONFIG_HID_BATTERY_STRENGTH */
655656

@@ -1515,11 +1516,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
15151516
return;
15161517

15171518
if (usage->type == EV_PWR) {
1518-
bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value);
1519-
1520-
if (!handled)
1521-
hidinput_update_battery(hid, value);
1522-
1519+
hidinput_update_battery(hid, usage->hid, value);
15231520
return;
15241521
}
15251522

drivers/hid/hid-logitech-dj.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1983,6 +1983,10 @@ static const struct hid_device_id logi_dj_receivers[] = {
19831983
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
19841984
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),
19851985
.driver_data = recvr_type_gaming_hidpp},
1986+
{ /* Logitech lightspeed receiver (0xc543) */
1987+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
1988+
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2),
1989+
.driver_data = recvr_type_gaming_hidpp},
19861990

19871991
{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
19881992
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),

drivers/hid/hid-logitech-hidpp.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4596,6 +4596,8 @@ static const struct hid_device_id hidpp_devices[] = {
45964596
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC094) },
45974597
{ /* Logitech G Pro X Superlight 2 Gaming Mouse over USB */
45984598
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC09b) },
4599+
{ /* Logitech G PRO 2 LIGHTSPEED Wireless Mouse over USB */
4600+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xc09a) },
45994601

46004602
{ /* G935 Gaming Headset */
46014603
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0x0a87),

drivers/hid/hid-mcp2221.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,10 @@ static int mcp2221_raw_event(struct hid_device *hdev,
906906
}
907907
if (data[2] == MCP2221_I2C_READ_COMPL ||
908908
data[2] == MCP2221_I2C_READ_PARTIAL) {
909+
if (!mcp->rxbuf || mcp->rxbuf_idx < 0 || data[3] > 60) {
910+
mcp->status = -EINVAL;
911+
break;
912+
}
909913
buf = mcp->rxbuf;
910914
memcpy(&buf[mcp->rxbuf_idx], &data[4], data[3]);
911915
mcp->rxbuf_idx = mcp->rxbuf_idx + data[3];

drivers/hid/hid-multitouch.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,6 +1503,14 @@ static const __u8 *mt_report_fixup(struct hid_device *hdev, __u8 *rdesc,
15031503
if (hdev->vendor == I2C_VENDOR_ID_GOODIX &&
15041504
(hdev->product == I2C_DEVICE_ID_GOODIX_01E8 ||
15051505
hdev->product == I2C_DEVICE_ID_GOODIX_01E9)) {
1506+
if (*size < 608) {
1507+
dev_info(
1508+
&hdev->dev,
1509+
"GT7868Q fixup: report descriptor is only %u bytes, skipping\n",
1510+
*size);
1511+
return rdesc;
1512+
}
1513+
15061514
if (rdesc[607] == 0x15) {
15071515
rdesc[607] = 0x25;
15081516
dev_info(

0 commit comments

Comments
 (0)