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;