Correctly handle signed/unsigned quantities in kernel HID parser.

Should fix PR kern/53605.
This commit is contained in:
jakllsch 2018-11-15 23:01:45 +00:00
parent fa57652bf8
commit 269297e942
5 changed files with 61 additions and 61 deletions

View File

@ -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 self, void *aux)
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);

View File

@ -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 hid_item *h)
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 hid_item *h)
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 hid_item *h)
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 hid_item *h)
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 hid_item *h)
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 hid_item *h)
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 hid_item *h)
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 hid_item *h)
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 hid_item *h)
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);

View File

@ -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;

View File

@ -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);

View File

@ -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;