* [PATCH] HID: core: add short report quirk and use it for GPD Win (2f24:0137)
@ 2026-04-07 17:32 Zhouwang Huang
2026-04-08 15:41 ` Benjamin Tissoires
0 siblings, 1 reply; 7+ messages in thread
From: Zhouwang Huang @ 2026-04-07 17:32 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, honjow
Cc: denis.benato, linux-kernel, linux-input
Commit 9e2a17d2e808 ("HID: gpd: fix report descriptor on GPD Win
handheld (2f24:0137)") used report_fixup to shrink Report Count from
63 to 11 so that short reports from firmware <= 1.09 would not be
rejected by hid_report_raw_event().
However, firmware 1.10 fixed the report length and now sends the full
63 bytes. Because report_fixup already shrank the descriptor,
usbhid allocates a 12-byte URB buffer — far too small for the 64-byte
transfer — causing continuous -EOVERFLOW on every interrupt-in URB.
The HID report descriptor and bcdDevice are identical across firmware
versions, so report_fixup cannot conditionally apply.
Replace the report_fixup driver with a new per-device quirk
HID_QUIRK_ALLOW_SHORT_REPORTS. When set, hid_report_raw_event()
zero-pads short reports instead of rejecting them — the same behaviour
the core had before commit 0a3fe972a7cb ("HID: core: Mitigate
potential OOB by removing bogus memset()"). The descriptor is left
unmodified so the URB buffer matches the declared report size and works
with any firmware version.
Remove hid-gpd.c, its Kconfig entry and Makefile line; the device is
now handled by hid-generic with the quirk applied from hid-quirks.c.
Fixes: 9e2a17d2e808 ("HID: gpd: fix report descriptor on GPD Win handheld (2f24:0137)")
Signed-off-by: Zhouwang Huang <honjow311@gmail.com>
---
drivers/hid/Kconfig | 10 --------
drivers/hid/Makefile | 1 -
drivers/hid/hid-core.c | 11 +++++----
drivers/hid/hid-gpd.c | 52 ----------------------------------------
drivers/hid/hid-quirks.c | 2 ++
include/linux/hid.h | 2 ++
6 files changed, 11 insertions(+), 67 deletions(-)
delete mode 100644 drivers/hid/hid-gpd.c
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 2159d0fb7020..c1d9f7c6a5f2 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -419,16 +419,6 @@ config HID_GLORIOUS
Support for Glorious PC Gaming Race mice such as
the Glorious Model O, O- and D.
-config HID_GPD
- tristate "GPD Win handheld OEM HID support"
- depends on USB_HID
- help
- Report descriptor fix for the OEM USB HID interface (GameSir
- 2f24:0137) found on GPD Win handhelds. The firmware declares 63-byte
- reports but only sends 11 bytes, which the HID core rejects.
-
- Say Y or M here if you use a GPD Win handheld with this interface.
-
config HID_HOLTEK
tristate "Holtek HID devices"
depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index f69cd6015465..e01838239ae6 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -53,7 +53,6 @@ obj-$(CONFIG_HID_ELO) += hid-elo.o
obj-$(CONFIG_HID_EVISION) += hid-evision.o
obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
obj-$(CONFIG_HID_FT260) += hid-ft260.o
-obj-$(CONFIG_HID_GPD) += hid-gpd.o
obj-$(CONFIG_HID_GEMBIRD) += hid-gembird.o
obj-$(CONFIG_HID_GFRM) += hid-gfrm.o
obj-$(CONFIG_HID_GLORIOUS) += hid-glorious.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index f5587b786f87..52e86f927a38 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2057,10 +2057,13 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *
rsize = max_buffer_size;
if (csize < rsize) {
- 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->quirks & HID_QUIRK_ALLOW_SHORT_REPORTS)) {
+ hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %d)\n",
+ report->id, rsize, csize);
+ ret = -EINVAL;
+ goto out;
+ }
+ memset(cdata + csize, 0, rsize - csize);
}
if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
diff --git a/drivers/hid/hid-gpd.c b/drivers/hid/hid-gpd.c
deleted file mode 100644
index 5b4d203e2499..000000000000
--- a/drivers/hid/hid-gpd.c
+++ /dev/null
@@ -1,52 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * HID report descriptor fixup for GPD Win handhelds.
- *
- * The OEM HID interface (VID 2f24 / GameSir, PID 0137) declares Report ID 1
- * with Report Count 63 (8-bit fields) for both Input and Feature, but the
- * firmware only sends 11 bytes of payload after the report ID.
- */
-
-#include <linux/hid.h>
-#include <linux/module.h>
-
-#include "hid-ids.h"
-
-#define RDESC_LEN 38
-#define RPT_COUNT_INPUT_OFF 21
-#define RPT_COUNT_FEATURE_OFF 34
-
-static const __u8 *gpd_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- unsigned int *rsize)
-{
- if (*rsize != RDESC_LEN)
- return rdesc;
-
- if (rdesc[RPT_COUNT_INPUT_OFF - 1] == 0x95 &&
- rdesc[RPT_COUNT_INPUT_OFF] == 0x3f &&
- rdesc[RPT_COUNT_FEATURE_OFF - 1] == 0x95 &&
- rdesc[RPT_COUNT_FEATURE_OFF] == 0x3f) {
- hid_info(hdev, "fixing report counts (63 -> 11 bytes)\n");
- rdesc[RPT_COUNT_INPUT_OFF] = 11;
- rdesc[RPT_COUNT_FEATURE_OFF] = 11;
- }
-
- return rdesc;
-}
-
-static const struct hid_device_id gpd_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_GAMESIR, USB_DEVICE_ID_GAMESIR_0137) },
- { }
-};
-MODULE_DEVICE_TABLE(hid, gpd_devices);
-
-static struct hid_driver gpd_driver = {
- .name = "gpd",
- .id_table = gpd_devices,
- .report_fixup = gpd_report_fixup,
-};
-
-module_hid_driver(gpd_driver);
-
-MODULE_DESCRIPTION("HID report descriptor fix for GPD Win handheld (GameSir 2f24:0137)");
-MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index f6be3ffee023..b9ae1442eba9 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -97,6 +97,8 @@ static const struct hid_device_id hid_quirks[] = {
HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_KISHI),
HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
+ { HID_USB_DEVICE(USB_VENDOR_ID_GAMESIR, USB_DEVICE_ID_GAMESIR_0137),
+ HID_QUIRK_ALLOW_SHORT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 31324609af4d..212dd13bfcfa 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -381,6 +381,7 @@ struct hid_item {
* | @HID_QUIRK_X_INVERT:
* | @HID_QUIRK_Y_INVERT:
* | @HID_QUIRK_IGNORE_MOUSE:
+ * | @HID_QUIRK_ALLOW_SHORT_REPORTS: accept shorter-than-expected reports, zero-pad
* | @HID_QUIRK_SKIP_OUTPUT_REPORTS:
* | @HID_QUIRK_SKIP_OUTPUT_REPORT_ID:
* | @HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP:
@@ -408,6 +409,7 @@ struct hid_item {
#define HID_QUIRK_X_INVERT BIT(12)
#define HID_QUIRK_Y_INVERT BIT(13)
#define HID_QUIRK_IGNORE_MOUSE BIT(14)
+#define HID_QUIRK_ALLOW_SHORT_REPORTS BIT(15)
#define HID_QUIRK_SKIP_OUTPUT_REPORTS BIT(16)
#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID BIT(17)
#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18)
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH] HID: core: add short report quirk and use it for GPD Win (2f24:0137) 2026-04-07 17:32 [PATCH] HID: core: add short report quirk and use it for GPD Win (2f24:0137) Zhouwang Huang @ 2026-04-08 15:41 ` Benjamin Tissoires 2026-04-08 16:07 ` Zhouwang Huang ` (2 more replies) 0 siblings, 3 replies; 7+ messages in thread From: Benjamin Tissoires @ 2026-04-08 15:41 UTC (permalink / raw) To: Zhouwang Huang; +Cc: Jiri Kosina, denis.benato, linux-kernel, linux-input Hi, Definitely not a big fan of that new quirk. The issue is that current hid-core fix is too restrictive because it doesn't have enough information, like the actual allocated buffer size. On Apr 08 2026, Zhouwang Huang wrote: > Commit 9e2a17d2e808 ("HID: gpd: fix report descriptor on GPD Win > handheld (2f24:0137)") used report_fixup to shrink Report Count from > 63 to 11 so that short reports from firmware <= 1.09 would not be > rejected by hid_report_raw_event(). > > However, firmware 1.10 fixed the report length and now sends the full > 63 bytes. Because report_fixup already shrank the descriptor, > usbhid allocates a 12-byte URB buffer — far too small for the 64-byte > transfer — causing continuous -EOVERFLOW on every interrupt-in URB. > The HID report descriptor and bcdDevice are identical across firmware > versions, so report_fixup cannot conditionally apply. OK, so if a firmware already fixed the bug, I'll drop 9e2a17d2e808 from for-next and not include it in the final 7.0 PR I'll need to send. We can tell people to upgrade to the latest firmware while I work on a proper fix. BTW, technically we could also not change the report descriptor if we detect the correct firmware version. That would be easier to implement than a global quirk. But hopefully we won't have to do anything and get the proper hid-core fix soon. Cheers, Benjamin > > Replace the report_fixup driver with a new per-device quirk > HID_QUIRK_ALLOW_SHORT_REPORTS. When set, hid_report_raw_event() > zero-pads short reports instead of rejecting them — the same behaviour > the core had before commit 0a3fe972a7cb ("HID: core: Mitigate > potential OOB by removing bogus memset()"). The descriptor is left > unmodified so the URB buffer matches the declared report size and works > with any firmware version. > > Remove hid-gpd.c, its Kconfig entry and Makefile line; the device is > now handled by hid-generic with the quirk applied from hid-quirks.c. > > Fixes: 9e2a17d2e808 ("HID: gpd: fix report descriptor on GPD Win handheld (2f24:0137)") > Signed-off-by: Zhouwang Huang <honjow311@gmail.com> > --- > drivers/hid/Kconfig | 10 -------- > drivers/hid/Makefile | 1 - > drivers/hid/hid-core.c | 11 +++++---- > drivers/hid/hid-gpd.c | 52 ---------------------------------------- > drivers/hid/hid-quirks.c | 2 ++ > include/linux/hid.h | 2 ++ > 6 files changed, 11 insertions(+), 67 deletions(-) > delete mode 100644 drivers/hid/hid-gpd.c > > diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig > index 2159d0fb7020..c1d9f7c6a5f2 100644 > --- a/drivers/hid/Kconfig > +++ b/drivers/hid/Kconfig > @@ -419,16 +419,6 @@ config HID_GLORIOUS > Support for Glorious PC Gaming Race mice such as > the Glorious Model O, O- and D. > > -config HID_GPD > - tristate "GPD Win handheld OEM HID support" > - depends on USB_HID > - help > - Report descriptor fix for the OEM USB HID interface (GameSir > - 2f24:0137) found on GPD Win handhelds. The firmware declares 63-byte > - reports but only sends 11 bytes, which the HID core rejects. > - > - Say Y or M here if you use a GPD Win handheld with this interface. > - > config HID_HOLTEK > tristate "Holtek HID devices" > depends on USB_HID > diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile > index f69cd6015465..e01838239ae6 100644 > --- a/drivers/hid/Makefile > +++ b/drivers/hid/Makefile > @@ -53,7 +53,6 @@ obj-$(CONFIG_HID_ELO) += hid-elo.o > obj-$(CONFIG_HID_EVISION) += hid-evision.o > obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o > obj-$(CONFIG_HID_FT260) += hid-ft260.o > -obj-$(CONFIG_HID_GPD) += hid-gpd.o > obj-$(CONFIG_HID_GEMBIRD) += hid-gembird.o > obj-$(CONFIG_HID_GFRM) += hid-gfrm.o > obj-$(CONFIG_HID_GLORIOUS) += hid-glorious.o > diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c > index f5587b786f87..52e86f927a38 100644 > --- a/drivers/hid/hid-core.c > +++ b/drivers/hid/hid-core.c > @@ -2057,10 +2057,13 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 * > rsize = max_buffer_size; > > if (csize < rsize) { > - 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->quirks & HID_QUIRK_ALLOW_SHORT_REPORTS)) { > + hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %d)\n", > + report->id, rsize, csize); > + ret = -EINVAL; > + goto out; > + } > + memset(cdata + csize, 0, rsize - csize); > } > > if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) > diff --git a/drivers/hid/hid-gpd.c b/drivers/hid/hid-gpd.c > deleted file mode 100644 > index 5b4d203e2499..000000000000 > --- a/drivers/hid/hid-gpd.c > +++ /dev/null > @@ -1,52 +0,0 @@ > -// SPDX-License-Identifier: GPL-2.0-or-later > -/* > - * HID report descriptor fixup for GPD Win handhelds. > - * > - * The OEM HID interface (VID 2f24 / GameSir, PID 0137) declares Report ID 1 > - * with Report Count 63 (8-bit fields) for both Input and Feature, but the > - * firmware only sends 11 bytes of payload after the report ID. > - */ > - > -#include <linux/hid.h> > -#include <linux/module.h> > - > -#include "hid-ids.h" > - > -#define RDESC_LEN 38 > -#define RPT_COUNT_INPUT_OFF 21 > -#define RPT_COUNT_FEATURE_OFF 34 > - > -static const __u8 *gpd_report_fixup(struct hid_device *hdev, __u8 *rdesc, > - unsigned int *rsize) > -{ > - if (*rsize != RDESC_LEN) > - return rdesc; > - > - if (rdesc[RPT_COUNT_INPUT_OFF - 1] == 0x95 && > - rdesc[RPT_COUNT_INPUT_OFF] == 0x3f && > - rdesc[RPT_COUNT_FEATURE_OFF - 1] == 0x95 && > - rdesc[RPT_COUNT_FEATURE_OFF] == 0x3f) { > - hid_info(hdev, "fixing report counts (63 -> 11 bytes)\n"); > - rdesc[RPT_COUNT_INPUT_OFF] = 11; > - rdesc[RPT_COUNT_FEATURE_OFF] = 11; > - } > - > - return rdesc; > -} > - > -static const struct hid_device_id gpd_devices[] = { > - { HID_USB_DEVICE(USB_VENDOR_ID_GAMESIR, USB_DEVICE_ID_GAMESIR_0137) }, > - { } > -}; > -MODULE_DEVICE_TABLE(hid, gpd_devices); > - > -static struct hid_driver gpd_driver = { > - .name = "gpd", > - .id_table = gpd_devices, > - .report_fixup = gpd_report_fixup, > -}; > - > -module_hid_driver(gpd_driver); > - > -MODULE_DESCRIPTION("HID report descriptor fix for GPD Win handheld (GameSir 2f24:0137)"); > -MODULE_LICENSE("GPL"); > diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c > index f6be3ffee023..b9ae1442eba9 100644 > --- a/drivers/hid/hid-quirks.c > +++ b/drivers/hid/hid-quirks.c > @@ -97,6 +97,8 @@ static const struct hid_device_id hid_quirks[] = { > HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, > { HID_USB_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_KISHI), > HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, > + { HID_USB_DEVICE(USB_VENDOR_ID_GAMESIR, USB_DEVICE_ID_GAMESIR_0137), > + HID_QUIRK_ALLOW_SHORT_REPORTS }, > { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, > { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, > { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, > diff --git a/include/linux/hid.h b/include/linux/hid.h > index 31324609af4d..212dd13bfcfa 100644 > --- a/include/linux/hid.h > +++ b/include/linux/hid.h > @@ -381,6 +381,7 @@ struct hid_item { > * | @HID_QUIRK_X_INVERT: > * | @HID_QUIRK_Y_INVERT: > * | @HID_QUIRK_IGNORE_MOUSE: > + * | @HID_QUIRK_ALLOW_SHORT_REPORTS: accept shorter-than-expected reports, zero-pad > * | @HID_QUIRK_SKIP_OUTPUT_REPORTS: > * | @HID_QUIRK_SKIP_OUTPUT_REPORT_ID: > * | @HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP: > @@ -408,6 +409,7 @@ struct hid_item { > #define HID_QUIRK_X_INVERT BIT(12) > #define HID_QUIRK_Y_INVERT BIT(13) > #define HID_QUIRK_IGNORE_MOUSE BIT(14) > +#define HID_QUIRK_ALLOW_SHORT_REPORTS BIT(15) > #define HID_QUIRK_SKIP_OUTPUT_REPORTS BIT(16) > #define HID_QUIRK_SKIP_OUTPUT_REPORT_ID BIT(17) > #define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18) > -- > 2.53.0 > > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] HID: core: add short report quirk and use it for GPD Win (2f24:0137) 2026-04-08 15:41 ` Benjamin Tissoires @ 2026-04-08 16:07 ` Zhouwang Huang 2026-04-08 19:30 ` Jiri Kosina 2026-04-14 8:11 ` Thorsten Leemhuis 2 siblings, 0 replies; 7+ messages in thread From: Zhouwang Huang @ 2026-04-08 16:07 UTC (permalink / raw) To: Benjamin Tissoires Cc: Jiri Kosina, denis.benato, linux-input, linux-kernel, honjow311 Hi Benjamin, Thanks. Agreed, a core fix that checks the actual buffer size would be much cleaner than a per-device quirk. Happy to test when it's ready. Thanks, Zhouwang ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] HID: core: add short report quirk and use it for GPD Win (2f24:0137) 2026-04-08 15:41 ` Benjamin Tissoires 2026-04-08 16:07 ` Zhouwang Huang @ 2026-04-08 19:30 ` Jiri Kosina 2026-04-14 8:11 ` Thorsten Leemhuis 2 siblings, 0 replies; 7+ messages in thread From: Jiri Kosina @ 2026-04-08 19:30 UTC (permalink / raw) To: Benjamin Tissoires Cc: Zhouwang Huang, denis.benato, linux-kernel, linux-input On Wed, 8 Apr 2026, Benjamin Tissoires wrote: > OK, so if a firmware already fixed the bug, I'll drop 9e2a17d2e808 from > for-next and not include it in the final 7.0 PR I'll need to send. Now dropped. Thanks, -- Jiri Kosina SUSE Labs ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] HID: core: add short report quirk and use it for GPD Win (2f24:0137) 2026-04-08 15:41 ` Benjamin Tissoires 2026-04-08 16:07 ` Zhouwang Huang 2026-04-08 19:30 ` Jiri Kosina @ 2026-04-14 8:11 ` Thorsten Leemhuis 2026-04-15 8:23 ` Benjamin Tissoires 2 siblings, 1 reply; 7+ messages in thread From: Thorsten Leemhuis @ 2026-04-14 8:11 UTC (permalink / raw) To: Benjamin Tissoires Cc: Jiri Kosina, denis.benato, linux-kernel, linux-input, honjow, Anj D, Zhouwang Huang, Linus Torvalds, Linux kernel regressions list On 4/8/26 17:41, Benjamin Tissoires wrote: > Definitely not a big fan of that new quirk. The issue is that current > hid-core fix is too restrictive because it doesn't have enough > information, like the actual allocated buffer size. > > On Apr 08 2026, Zhouwang Huang wrote: >> Commit 9e2a17d2e808 ("HID: gpd: fix report descriptor on GPD Win >> handheld (2f24:0137)") used report_fixup to shrink Report Count from >> 63 to 11 so that short reports from firmware <= 1.09 would not be >> rejected by hid_report_raw_event(). >> >> However, firmware 1.10 fixed the report length and now sends the full >> 63 bytes. Because report_fixup already shrank the descriptor, >> usbhid allocates a 12-byte URB buffer — far too small for the 64-byte >> transfer — causing continuous -EOVERFLOW on every interrupt-in URB. >> The HID report descriptor and bcdDevice are identical across firmware >> versions, so report_fixup cannot conditionally apply. > > OK, so if a firmware already fixed the bug, I'll drop 9e2a17d2e808 from > for-next and not include it in the final 7.0 PR I'll need to send. Well, that meanwhile dropped commit 9e2a17d2e808 ("HID: gpd: fix report descriptor on GPD Win handheld (2f24:0137)") was supposed to fix a regression honjow (now CCed) reported on 2026-03-23: https://bugzilla.kernel.org/show_bug.cgi?id=221271 https://lore.kernel.org/all/20260324013847.68024-1-honjow311@gmail.com/ So it is still unfixed as of now, I assume? Side note: was honjow even notified about dropping the commit? > We can tell people to upgrade to the latest firmware Well, that should not be required by users when it comes to regressions -- unless maybe no other way to fix a severe issue can be found. Is that the case here? > while I work on a proper fix. How far is a proper fix away? And will that be GPD Win specific, or fix issues with other issues, too. Because Anj D (now CCed) recently reported a flooded dmesg caused by 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus memset()") with a APC UPS (USB VID/PID 051D:0002): https://lore.kernel.org/all/MW5PR84MB135613E7947113897DD9FDA4C7272@MW5PR84MB1356.NAMPRD84.PROD.OUTLOOK.COM/ That's with 6.19.12, as the commit was recently backported to 6.18.y and 6.19.y. Ciao, Thorsten > BTW, technically we could also not change the report descriptor if we > detect the correct firmware version. That would be easier to implement > than a global quirk. But hopefully we won't have to do anything and get > the proper hid-core fix soon. > > Cheers, > Benjamin > >> >> Replace the report_fixup driver with a new per-device quirk >> HID_QUIRK_ALLOW_SHORT_REPORTS. When set, hid_report_raw_event() >> zero-pads short reports instead of rejecting them — the same behaviour >> the core had before commit 0a3fe972a7cb ("HID: core: Mitigate >> potential OOB by removing bogus memset()"). The descriptor is left >> unmodified so the URB buffer matches the declared report size and works >> with any firmware version. >> >> Remove hid-gpd.c, its Kconfig entry and Makefile line; the device is >> now handled by hid-generic with the quirk applied from hid-quirks.c. >> >> Fixes: 9e2a17d2e808 ("HID: gpd: fix report descriptor on GPD Win handheld (2f24:0137)") >> Signed-off-by: Zhouwang Huang <honjow311@gmail.com> >> --- >> drivers/hid/Kconfig | 10 -------- >> drivers/hid/Makefile | 1 - >> drivers/hid/hid-core.c | 11 +++++---- >> drivers/hid/hid-gpd.c | 52 ---------------------------------------- >> drivers/hid/hid-quirks.c | 2 ++ >> include/linux/hid.h | 2 ++ >> 6 files changed, 11 insertions(+), 67 deletions(-) >> delete mode 100644 drivers/hid/hid-gpd.c >> >> diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig >> index 2159d0fb7020..c1d9f7c6a5f2 100644 >> --- a/drivers/hid/Kconfig >> +++ b/drivers/hid/Kconfig >> @@ -419,16 +419,6 @@ config HID_GLORIOUS >> Support for Glorious PC Gaming Race mice such as >> the Glorious Model O, O- and D. >> >> -config HID_GPD >> - tristate "GPD Win handheld OEM HID support" >> - depends on USB_HID >> - help >> - Report descriptor fix for the OEM USB HID interface (GameSir >> - 2f24:0137) found on GPD Win handhelds. The firmware declares 63-byte >> - reports but only sends 11 bytes, which the HID core rejects. >> - >> - Say Y or M here if you use a GPD Win handheld with this interface. >> - >> config HID_HOLTEK >> tristate "Holtek HID devices" >> depends on USB_HID >> diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile >> index f69cd6015465..e01838239ae6 100644 >> --- a/drivers/hid/Makefile >> +++ b/drivers/hid/Makefile >> @@ -53,7 +53,6 @@ obj-$(CONFIG_HID_ELO) += hid-elo.o >> obj-$(CONFIG_HID_EVISION) += hid-evision.o >> obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o >> obj-$(CONFIG_HID_FT260) += hid-ft260.o >> -obj-$(CONFIG_HID_GPD) += hid-gpd.o >> obj-$(CONFIG_HID_GEMBIRD) += hid-gembird.o >> obj-$(CONFIG_HID_GFRM) += hid-gfrm.o >> obj-$(CONFIG_HID_GLORIOUS) += hid-glorious.o >> diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c >> index f5587b786f87..52e86f927a38 100644 >> --- a/drivers/hid/hid-core.c >> +++ b/drivers/hid/hid-core.c >> @@ -2057,10 +2057,13 @@ int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 * >> rsize = max_buffer_size; >> >> if (csize < rsize) { >> - 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->quirks & HID_QUIRK_ALLOW_SHORT_REPORTS)) { >> + hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs %d)\n", >> + report->id, rsize, csize); >> + ret = -EINVAL; >> + goto out; >> + } >> + memset(cdata + csize, 0, rsize - csize); >> } >> >> if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) >> diff --git a/drivers/hid/hid-gpd.c b/drivers/hid/hid-gpd.c >> deleted file mode 100644 >> index 5b4d203e2499..000000000000 >> --- a/drivers/hid/hid-gpd.c >> +++ /dev/null >> @@ -1,52 +0,0 @@ >> -// SPDX-License-Identifier: GPL-2.0-or-later >> -/* >> - * HID report descriptor fixup for GPD Win handhelds. >> - * >> - * The OEM HID interface (VID 2f24 / GameSir, PID 0137) declares Report ID 1 >> - * with Report Count 63 (8-bit fields) for both Input and Feature, but the >> - * firmware only sends 11 bytes of payload after the report ID. >> - */ >> - >> -#include <linux/hid.h> >> -#include <linux/module.h> >> - >> -#include "hid-ids.h" >> - >> -#define RDESC_LEN 38 >> -#define RPT_COUNT_INPUT_OFF 21 >> -#define RPT_COUNT_FEATURE_OFF 34 >> - >> -static const __u8 *gpd_report_fixup(struct hid_device *hdev, __u8 *rdesc, >> - unsigned int *rsize) >> -{ >> - if (*rsize != RDESC_LEN) >> - return rdesc; >> - >> - if (rdesc[RPT_COUNT_INPUT_OFF - 1] == 0x95 && >> - rdesc[RPT_COUNT_INPUT_OFF] == 0x3f && >> - rdesc[RPT_COUNT_FEATURE_OFF - 1] == 0x95 && >> - rdesc[RPT_COUNT_FEATURE_OFF] == 0x3f) { >> - hid_info(hdev, "fixing report counts (63 -> 11 bytes)\n"); >> - rdesc[RPT_COUNT_INPUT_OFF] = 11; >> - rdesc[RPT_COUNT_FEATURE_OFF] = 11; >> - } >> - >> - return rdesc; >> -} >> - >> -static const struct hid_device_id gpd_devices[] = { >> - { HID_USB_DEVICE(USB_VENDOR_ID_GAMESIR, USB_DEVICE_ID_GAMESIR_0137) }, >> - { } >> -}; >> -MODULE_DEVICE_TABLE(hid, gpd_devices); >> - >> -static struct hid_driver gpd_driver = { >> - .name = "gpd", >> - .id_table = gpd_devices, >> - .report_fixup = gpd_report_fixup, >> -}; >> - >> -module_hid_driver(gpd_driver); >> - >> -MODULE_DESCRIPTION("HID report descriptor fix for GPD Win handheld (GameSir 2f24:0137)"); >> -MODULE_LICENSE("GPL"); >> diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c >> index f6be3ffee023..b9ae1442eba9 100644 >> --- a/drivers/hid/hid-quirks.c >> +++ b/drivers/hid/hid-quirks.c >> @@ -97,6 +97,8 @@ static const struct hid_device_id hid_quirks[] = { >> HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, >> { HID_USB_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_KISHI), >> HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, >> + { HID_USB_DEVICE(USB_VENDOR_ID_GAMESIR, USB_DEVICE_ID_GAMESIR_0137), >> + HID_QUIRK_ALLOW_SHORT_REPORTS }, >> { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, >> { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, >> { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, >> diff --git a/include/linux/hid.h b/include/linux/hid.h >> index 31324609af4d..212dd13bfcfa 100644 >> --- a/include/linux/hid.h >> +++ b/include/linux/hid.h >> @@ -381,6 +381,7 @@ struct hid_item { >> * | @HID_QUIRK_X_INVERT: >> * | @HID_QUIRK_Y_INVERT: >> * | @HID_QUIRK_IGNORE_MOUSE: >> + * | @HID_QUIRK_ALLOW_SHORT_REPORTS: accept shorter-than-expected reports, zero-pad >> * | @HID_QUIRK_SKIP_OUTPUT_REPORTS: >> * | @HID_QUIRK_SKIP_OUTPUT_REPORT_ID: >> * | @HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP: >> @@ -408,6 +409,7 @@ struct hid_item { >> #define HID_QUIRK_X_INVERT BIT(12) >> #define HID_QUIRK_Y_INVERT BIT(13) >> #define HID_QUIRK_IGNORE_MOUSE BIT(14) >> +#define HID_QUIRK_ALLOW_SHORT_REPORTS BIT(15) >> #define HID_QUIRK_SKIP_OUTPUT_REPORTS BIT(16) >> #define HID_QUIRK_SKIP_OUTPUT_REPORT_ID BIT(17) >> #define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18) >> -- >> 2.53.0 >> >> > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] HID: core: add short report quirk and use it for GPD Win (2f24:0137) 2026-04-14 8:11 ` Thorsten Leemhuis @ 2026-04-15 8:23 ` Benjamin Tissoires 2026-04-15 9:10 ` Thorsten Leemhuis 0 siblings, 1 reply; 7+ messages in thread From: Benjamin Tissoires @ 2026-04-15 8:23 UTC (permalink / raw) To: Thorsten Leemhuis Cc: Jiri Kosina, denis.benato, linux-kernel, linux-input, honjow, Anj D, Linus Torvalds, Linux kernel regressions list On Apr 14 2026, Thorsten Leemhuis wrote: > On 4/8/26 17:41, Benjamin Tissoires wrote: > > Definitely not a big fan of that new quirk. The issue is that current > > hid-core fix is too restrictive because it doesn't have enough > > information, like the actual allocated buffer size. > > > > On Apr 08 2026, Zhouwang Huang wrote: > >> Commit 9e2a17d2e808 ("HID: gpd: fix report descriptor on GPD Win > >> handheld (2f24:0137)") used report_fixup to shrink Report Count from > >> 63 to 11 so that short reports from firmware <= 1.09 would not be > >> rejected by hid_report_raw_event(). > >> > >> However, firmware 1.10 fixed the report length and now sends the full > >> 63 bytes. Because report_fixup already shrank the descriptor, > >> usbhid allocates a 12-byte URB buffer — far too small for the 64-byte > >> transfer — causing continuous -EOVERFLOW on every interrupt-in URB. > >> The HID report descriptor and bcdDevice are identical across firmware > >> versions, so report_fixup cannot conditionally apply. > > > > OK, so if a firmware already fixed the bug, I'll drop 9e2a17d2e808 from > > for-next and not include it in the final 7.0 PR I'll need to send. > > Well, that meanwhile dropped commit 9e2a17d2e808 ("HID: gpd: fix report > descriptor on GPD Win handheld (2f24:0137)") was supposed to fix a > regression honjow (now CCed) reported on 2026-03-23: > https://bugzilla.kernel.org/show_bug.cgi?id=221271 > https://lore.kernel.org/all/20260324013847.68024-1-honjow311@gmail.com/ > > So it is still unfixed as of now, I assume? correct. But the HW is faulty and a new firmware version works, so it's not like there is no options. But... > > Side note: was honjow even notified about dropping the commit? Not sure we replied to the original thread. That's an omission from us, but OTH, the "fix" was only in linux-next, never in a realease kernel, so it was just a delay introduced. > > > We can tell people to upgrade to the latest firmware > > Well, that should not be required by users when it comes to regressions > -- unless maybe no other way to fix a severe issue can be found. Is that > the case here? Sigh. The fix that was introduced in the previous release cycle was a "security" one. Which explained it had a fast path in being merged into the kernel and into stable. I hate those but there was something fundamentally wrong in the hid core code. We already got numerous reports that the fix is not breaking other devices but is way too verbose, so a proper fix is on its way, as soon as I managed to properly test it on my machine. > > > while I work on a proper fix. > > How far is a proper fix away? And will that be GPD Win specific, or fix Should be out today or tomorrow, depending if my machine still randomly freeze because of the latest 7.0-rc bugs GPD specific -> no, it's basically restoring the old behaviour where we authorize shorter reports, but only if the provided buffer is big enough. This is is the case when we are dealing with an actual call from a transport layer like USB or I2C, but not from uhid. > issues with other issues, too. Because Anj D (now CCed) recently > reported a flooded dmesg caused by 0a3fe972a7cb ("HID: core: Mitigate > potential OOB by removing bogus memset()") with a APC UPS (USB VID/PID > 051D:0002): > https://lore.kernel.org/all/MW5PR84MB135613E7947113897DD9FDA4C7272@MW5PR84MB1356.NAMPRD84.PROD.OUTLOOK.COM/ > > That's with 6.19.12, as the commit was recently backported to 6.18.y and > 6.19.y. Yes, again, please redirect your wrath to the persons who decided that this kind of bugs (that we admitedly have to fix) are security in some cases :) But yeah, security bugs are an annoyance for anybody, and we are far from seeing the end of it. Cheers, Benjamin ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] HID: core: add short report quirk and use it for GPD Win (2f24:0137) 2026-04-15 8:23 ` Benjamin Tissoires @ 2026-04-15 9:10 ` Thorsten Leemhuis 0 siblings, 0 replies; 7+ messages in thread From: Thorsten Leemhuis @ 2026-04-15 9:10 UTC (permalink / raw) To: Benjamin Tissoires Cc: Jiri Kosina, denis.benato, linux-kernel, linux-input, honjow, Anj D, Linus Torvalds, Linux kernel regressions list On 4/15/26 10:23, Benjamin Tissoires wrote: > On Apr 14 2026, Thorsten Leemhuis wrote: >> On 4/8/26 17:41, Benjamin Tissoires wrote: Thx for the reply. > [...] >>> We can tell people to upgrade to the latest firmware >> Well, that should not be required by users when it comes to regressions >> -- unless maybe no other way to fix a severe issue can be found. Is that >> the case here? > Sigh. The fix that was introduced in the previous release cycle was a > "security" one. [...] Yeah, I figured and should have made this more obvious in my reply (sorry), but it's hard to distinguish "this is a fix for something that is unlikely to happen" and is fine to be reverted again temporarily in case of regressions from those where that's not a good idea. And I wanted to know which of it it was, but clearly did so poorly. Sorry! >> How far is a proper fix away? And will that be GPD Win specific, or fix > Should be out today or tomorrow, [...] Great, thx! Ciao, Thorsten ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-04-15 9:17 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-04-07 17:32 [PATCH] HID: core: add short report quirk and use it for GPD Win (2f24:0137) Zhouwang Huang 2026-04-08 15:41 ` Benjamin Tissoires 2026-04-08 16:07 ` Zhouwang Huang 2026-04-08 19:30 ` Jiri Kosina 2026-04-14 8:11 ` Thorsten Leemhuis 2026-04-15 8:23 ` Benjamin Tissoires 2026-04-15 9:10 ` Thorsten Leemhuis
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox