Module Name:    src
Committed By:   jakllsch
Date:           Thu Nov 15 23:01:46 UTC 2018

Modified Files:
        src/sys/dev/bluetooth: bthidev.c
        src/sys/dev/hid: hid.c hid.h
        src/sys/dev/i2c: ihidev.c
        src/sys/dev/usb: uhidev.c

Log Message:
Correctly handle signed/unsigned quantities in kernel HID parser.

Should fix PR kern/53605.


To generate a diff of this commit:
cvs rdiff -u -r1.30 -r1.31 src/sys/dev/bluetooth/bthidev.c
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/hid/hid.c src/sys/dev/hid/hid.h
cvs rdiff -u -r1.5 -r1.6 src/sys/dev/i2c/ihidev.c
cvs rdiff -u -r1.73 -r1.74 src/sys/dev/usb/uhidev.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/bluetooth/bthidev.c
diff -u src/sys/dev/bluetooth/bthidev.c:1.30 src/sys/dev/bluetooth/bthidev.c:1.31
--- src/sys/dev/bluetooth/bthidev.c:1.30	Sun Dec 10 17:03:07 2017
+++ src/sys/dev/bluetooth/bthidev.c	Thu Nov 15 23:01:45 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: bthidev.c,v 1.30 2017/12/10 17:03:07 bouyer Exp $	*/
+/*	$NetBSD: bthidev.c,v 1.31 2018/11/15 23:01:45 jakllsch Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bthidev.c,v 1.30 2017/12/10 17:03:07 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bthidev.c,v 1.31 2018/11/15 23:01:45 jakllsch Exp $");
 
 #include <sys/param.h>
 #include <sys/condvar.h>
@@ -284,7 +284,7 @@ bthidev_attach(device_t parent, device_t
 	h.report_ID = 0;
 	d = hid_start_parse(desc, dlen, hid_none);
 	while (hid_get_item(d, &h)) {
-		if (h.report_ID > maxid)
+		if ((int)h.report_ID > maxid)
 			maxid = h.report_ID;
 	}
 	hid_end_parse(d);

Index: src/sys/dev/hid/hid.c
diff -u src/sys/dev/hid/hid.c:1.2 src/sys/dev/hid/hid.c:1.3
--- src/sys/dev/hid/hid.c:1.2	Mon Sep  3 16:29:31 2018
+++ src/sys/dev/hid/hid.c	Thu Nov 15 23:01:45 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: hid.c,v 1.2 2018/09/03 16:29:31 riastradh Exp $	*/
+/*	$NetBSD: hid.c,v 1.3 2018/11/15 23:01:45 jakllsch Exp $	*/
 /*	$FreeBSD: src/sys/dev/usb/hid.c,v 1.11 1999/11/17 22:33:39 n_hibma Exp $ */
 
 /*
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hid.c,v 1.2 2018/09/03 16:29:31 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hid.c,v 1.3 2018/11/15 23:01:45 jakllsch Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -122,6 +122,7 @@ hid_get_item(struct hid_data *s, struct 
 	uint32_t oldpos;
 	const u_char *data;
 	int32_t dval;
+	uint32_t uval;
 	const u_char *p;
 	struct hid_item *hi;
 	int i;
@@ -173,13 +174,17 @@ hid_get_item(struct hid_data *s, struct 
 		switch(bSize) {
 		case 0:
 			dval = 0;
+			uval = dval;
 			break;
 		case 1:
-			dval = (int8_t)*data++;
+			dval = *data++;
+			uval = dval;
+			dval = (int8_t)dval;
 			break;
 		case 2:
 			dval = *data++;
 			dval |= *data++ << 8;
+			uval = dval;
 			dval = (int16_t)dval;
 			break;
 		case 4:
@@ -187,6 +192,7 @@ hid_get_item(struct hid_data *s, struct 
 			dval |= *data++ << 8;
 			dval |= *data++ << 16;
 			dval |= *data++ << 24;
+			uval = dval;
 			dval = (int32_t)dval;
 			break;
 		default:
@@ -194,8 +200,8 @@ hid_get_item(struct hid_data *s, struct 
 			continue;
 		}
 
-		DPRINTFN(5,("hid_get_item: bType=%d bTag=%d dval=%d\n",
-			 bType, bTag, dval));
+		DPRINTFN(5,("hid_get_item: bType=%d bTag=%d dval=%d uval=%u\n",
+			 bType, bTag, dval, uval));
 		switch (bType) {
 		case 0:			/* Main */
 			switch (bTag) {
@@ -209,7 +215,7 @@ hid_get_item(struct hid_data *s, struct 
 					continue;
 				}
 				c->kind = retkind;
-				c->flags = dval;
+				c->flags = uval;
 				if (c->flags & HIO_VARIABLE) {
 					s->multimax = c->loc.count;
 					s->multi = 0;
@@ -242,7 +248,7 @@ hid_get_item(struct hid_data *s, struct 
 				goto ret;
 			case 10:	/* Collection */
 				c->kind = hid_collection;
-				c->collection = dval;
+				c->collection = uval;
 				c->collevel++;
 				*h = *c;
 				hid_clear_local(c);
@@ -265,7 +271,7 @@ hid_get_item(struct hid_data *s, struct 
 		case 1:		/* Global */
 			switch (bTag) {
 			case 0:
-				c->_usage_page = dval << 16;
+				c->_usage_page = uval << 16;
 				break;
 			case 1:
 				c->logical_minimum = dval;
@@ -280,20 +286,20 @@ hid_get_item(struct hid_data *s, struct 
 				c->physical_maximum = dval;
 				break;
 			case 5:
-				c->unit_exponent = dval;
+				c->unit_exponent = uval;
 				break;
 			case 6:
-				c->unit = dval;
+				c->unit = uval;
 				break;
 			case 7:
-				c->loc.size = dval;
+				c->loc.size = uval;
 				break;
 			case 8:
-				c->report_ID = dval;
+				c->report_ID = uval;
 				c->loc.pos = 0;
 				break;
 			case 9:
-				c->loc.count = dval;
+				c->loc.count = uval;
 				break;
 			case 10: /* Push */
 				hi = kmem_alloc(sizeof(*hi), KM_SLEEP);
@@ -317,50 +323,44 @@ hid_get_item(struct hid_data *s, struct 
 		case 2:		/* Local */
 			switch (bTag) {
 			case 0:
-				if (bSize == 1)
-					dval = c->_usage_page | (dval&0xff);
-				else if (bSize == 2)
-					dval = c->_usage_page | (dval&0xffff);
-				c->usage = dval;
+				if (bSize < 4)
+					uval = c->_usage_page | uval;
+				c->usage = uval;
 				if (s->nu < MAXUSAGE)
-					s->usages[s->nu++] = dval;
+					s->usages[s->nu++] = uval;
 				/* else XXX */
 				break;
 			case 1:
 				s->minset = 1;
-				if (bSize == 1)
-					dval = c->_usage_page | (dval&0xff);
-				else if (bSize == 2)
-					dval = c->_usage_page | (dval&0xffff);
-				c->usage_minimum = dval;
+				if (bSize < 4)
+					uval = c->_usage_page | uval;
+				c->usage_minimum = uval;
 				break;
 			case 2:
-				if (bSize == 1)
-					dval = c->_usage_page | (dval&0xff);
-				else if (bSize == 2)
-					dval = c->_usage_page | (dval&0xffff);
-				c->usage_maximum = dval;
+				if (bSize < 4)
+					uval = c->_usage_page | uval;
+				c->usage_maximum = uval;
 				break;
 			case 3:
-				c->designator_index = dval;
+				c->designator_index = uval;
 				break;
 			case 4:
-				c->designator_minimum = dval;
+				c->designator_minimum = uval;
 				break;
 			case 5:
-				c->designator_maximum = dval;
+				c->designator_maximum = uval;
 				break;
 			case 7:
-				c->string_index = dval;
+				c->string_index = uval;
 				break;
 			case 8:
-				c->string_minimum = dval;
+				c->string_minimum = uval;
 				break;
 			case 9:
-				c->string_maximum = dval;
+				c->string_maximum = uval;
 				break;
 			case 10:
-				c->set_delimiter = dval;
+				c->set_delimiter = uval;
 				break;
 			default:
 				aprint_normal("Local bTag=%d\n", bTag);
Index: src/sys/dev/hid/hid.h
diff -u src/sys/dev/hid/hid.h:1.2 src/sys/dev/hid/hid.h:1.3
--- src/sys/dev/hid/hid.h:1.2	Sun Dec 10 20:38:14 2017
+++ src/sys/dev/hid/hid.h	Thu Nov 15 23:01:45 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: hid.h,v 1.2 2017/12/10 20:38:14 bouyer Exp $	*/
+/*	$NetBSD: hid.h,v 1.3 2018/11/15 23:01:45 jakllsch Exp $	*/
 /*	$FreeBSD: src/sys/dev/usb/hid.h,v 1.7 1999/11/17 22:33:40 n_hibma Exp $ */
 
 /*
@@ -53,27 +53,27 @@ struct hid_location {
 
 struct hid_item {
 	/* Global */
-	int32_t _usage_page;
+	uint32_t _usage_page;
 	int32_t logical_minimum;
 	int32_t logical_maximum;
 	int32_t physical_minimum;
 	int32_t physical_maximum;
-	int32_t unit_exponent;
-	int32_t unit;
-	int32_t report_ID;
+	uint32_t unit_exponent;
+	uint32_t unit;
+	uint32_t report_ID;
 	/* Local */
-	int32_t usage;
-	int32_t usage_minimum;
-	int32_t usage_maximum;
-	int32_t designator_index;
-	int32_t designator_minimum;
-	int32_t designator_maximum;
-	int32_t string_index;
-	int32_t string_minimum;
-	int32_t string_maximum;
-	int32_t set_delimiter;
+	uint32_t usage;
+	uint32_t usage_minimum;
+	uint32_t usage_maximum;
+	uint32_t designator_index;
+	uint32_t designator_minimum;
+	uint32_t designator_maximum;
+	uint32_t string_index;
+	uint32_t string_minimum;
+	uint32_t string_maximum;
+	uint32_t set_delimiter;
 	/* Misc */
-	int32_t collection;
+	uint32_t collection;
 	int collevel;
 	enum hid_kind kind;
 	uint32_t flags;

Index: src/sys/dev/i2c/ihidev.c
diff -u src/sys/dev/i2c/ihidev.c:1.5 src/sys/dev/i2c/ihidev.c:1.6
--- src/sys/dev/i2c/ihidev.c:1.5	Tue Jun 26 06:03:57 2018
+++ src/sys/dev/i2c/ihidev.c	Thu Nov 15 23:01:45 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: ihidev.c,v 1.5 2018/06/26 06:03:57 thorpej Exp $ */
+/* $NetBSD: ihidev.c,v 1.6 2018/11/15 23:01:45 jakllsch Exp $ */
 /* $OpenBSD ihidev.c,v 1.13 2017/04/08 02:57:23 deraadt Exp $ */
 
 /*-
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ihidev.c,v 1.5 2018/06/26 06:03:57 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ihidev.c,v 1.6 2018/11/15 23:01:45 jakllsch Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -725,7 +725,7 @@ ihidev_maxrepid(void *buf, int len)
 	maxid = -1;
 	h.report_ID = 0;
 	for (d = hid_start_parse(buf, len, hid_none); hid_get_item(d, &h); )
-		if (h.report_ID > maxid)
+		if ((int)h.report_ID > maxid)
 			maxid = h.report_ID;
 	hid_end_parse(d);
 

Index: src/sys/dev/usb/uhidev.c
diff -u src/sys/dev/usb/uhidev.c:1.73 src/sys/dev/usb/uhidev.c:1.74
--- src/sys/dev/usb/uhidev.c:1.73	Sun Dec 10 17:03:07 2017
+++ src/sys/dev/usb/uhidev.c	Thu Nov 15 23:01:46 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhidev.c,v 1.73 2017/12/10 17:03:07 bouyer Exp $	*/
+/*	$NetBSD: uhidev.c,v 1.74 2018/11/15 23:01:46 jakllsch Exp $	*/
 
 /*
  * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.73 2017/12/10 17:03:07 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.74 2018/11/15 23:01:46 jakllsch Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -395,7 +395,7 @@ uhidev_maxrepid(void *buf, int len)
 	maxid = -1;
 	h.report_ID = 0;
 	for (d = hid_start_parse(buf, len, hid_none); hid_get_item(d, &h); )
-		if (h.report_ID > maxid)
+		if ((int)h.report_ID > maxid)
 			maxid = h.report_ID;
 	hid_end_parse(d);
 	return maxid;

Reply via email to