Index | Thread | Search

From:
Jonathan Matthew <jonathan@d14n.org>
Subject:
hid parser report count limit
To:
tech@openbsd.org
Date:
Sun, 26 Oct 2025 20:02:23 +1000

Download raw body.

Thread
  • Jonathan Matthew:

    hid parser report count limit

In FreeBSD, which is where our HID parser comes from, the report count
limit for HID usages has been increased from 255 to 1024 here:
https://reviews.freebsd.org/D16357 
to fix some touchscreens and keyboards, and then to 2048 here:
https://github.com/freebsd/freebsd-src/commit/1af51473bc9a8ab4bd7f2c9c6cce890f0d5fc638
to fix some unspecified devices.

I don't have any devices that this fixes, but I figure it makes sense
to pull in these changes anyway.  I found this while looking at the
Acemagic S1 LCD display, which needs some changes to uhidev to work
at all.

ok?

Index: hid.c
===================================================================
RCS file: /cvs/src/sys/dev/hid/hid.c,v
diff -u -p -u -p -r1.8 hid.c
--- hid.c	21 Jul 2025 21:46:40 -0000	1.8
+++ hid.c	26 Oct 2025 09:47:48 -0000
@@ -47,6 +47,7 @@
 #define	MAXUSAGE 64
 #define	MAXPUSH 4
 #define	MAXID 16
+#define	MAXLOCCNT 2048
 
 struct hid_pos_data {
 	int32_t rid;
@@ -64,10 +65,10 @@ struct hid_data {
 	int32_t usage_last;	/* last seen usage */
 	uint32_t loc_size;	/* last seen size */
 	uint32_t loc_count;	/* last seen count */
+	uint32_t ncount;	/* end usage item count */
+	uint32_t icount;	/* current usage item count */
 	enum hid_kind kind;
 	uint8_t	pushlevel;	/* current pushlevel */
-	uint8_t	ncount;		/* end usage item count */
-	uint8_t icount;		/* current usage item count */
 	uint8_t	nusage;		/* end "usages_min/max" index */
 	uint8_t	iusage;		/* current "usages_min/max" index */
 	uint8_t ousage;		/* current "usages_min/max" offset */
@@ -300,17 +301,18 @@ hid_get_item(struct hid_data *s, struct 
 			switch (bTag) {
 			case 8:	/* Input */
 				c->kind = hid_input;
-				c->flags = dval;
 		ret:
+				c->flags = dval;
 				c->loc.count = s->loc_count;
 				c->loc.size = s->loc_size;
 
 				if (c->flags & HIO_VARIABLE) {
 					/* range check usage count */
-					if (c->loc.count > 255) {
+					if (c->loc.count > MAXLOCCNT) {
 						DPRINTF("Number of "
-						    "items truncated to 255\n");
-						s->ncount = 255;
+						    "items truncated to %u\n",
+						    MAXLOCCNT);
+						s->ncount = MAXLOCCNT;
 					} else
 						s->ncount = c->loc.count;
 
@@ -326,7 +328,6 @@ hid_get_item(struct hid_data *s, struct 
 
 			case 9:	/* Output */
 				c->kind = hid_output;
-				c->flags = dval;
 				goto ret;
 			case 10:	/* Collection */
 				c->kind = hid_collection;
@@ -337,7 +338,6 @@ hid_get_item(struct hid_data *s, struct 
 				return (1);
 			case 11:	/* Feature */
 				c->kind = hid_feature;
-				c->flags = dval;
 				goto ret;
 			case 12:	/* End collection */
 				c->kind = hid_endcollection;