diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-09 20:16:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-09 20:16:11 -0400 |
commit | 092150a25cb7bd6a79aa00bb1ad131063f58073d (patch) | |
tree | bc182ea7bb8f5b83c6853ce407483a8814076e21 | |
parent | bdf33113d89f70186ffb6674e925fa9b8a0266b1 (diff) | |
parent | 4f65245f2d178b9cba48350620d76faa4a098841 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID fixes from Jiri Kosina:
- spectrev1 pattern fix in hiddev from Gustavo A. R. Silva
- bounds check fix for hid-debug from Daniel Rosenberg
- regression fix for HID autobinding from Benjamin Tissoires
- removal of excessive logging from i2c-hid driver from Jason Andryuk
- fix specific to 2nd generation of Wacom Intuos devices from Jason
Gerecke
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
HID: hiddev: fix potential Spectre v1
HID: i2c-hid: Fix "incomplete report" noise
HID: wacom: Correct touch maximum XY of 2nd-gen Intuos
HID: debug: check length before copy_to_user()
HID: core: allow concurrent registration of drivers
-rw-r--r-- | drivers/hid/hid-core.c | 5 | ||||
-rw-r--r-- | drivers/hid/hid-debug.c | 8 | ||||
-rw-r--r-- | drivers/hid/i2c-hid/i2c-hid.c | 2 | ||||
-rw-r--r-- | drivers/hid/usbhid/hiddev.c | 11 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.c | 10 | ||||
-rw-r--r-- | include/linux/hid.h | 3 |
6 files changed, 33 insertions, 6 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index f858cc72011d..3942ee61bd1c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1952,6 +1952,8 @@ static int hid_device_probe(struct device *dev) | |||
1952 | } | 1952 | } |
1953 | hdev->io_started = false; | 1953 | hdev->io_started = false; |
1954 | 1954 | ||
1955 | clear_bit(ffs(HID_STAT_REPROBED), &hdev->status); | ||
1956 | |||
1955 | if (!hdev->driver) { | 1957 | if (!hdev->driver) { |
1956 | id = hid_match_device(hdev, hdrv); | 1958 | id = hid_match_device(hdev, hdrv); |
1957 | if (id == NULL) { | 1959 | if (id == NULL) { |
@@ -2215,7 +2217,8 @@ static int __hid_bus_reprobe_drivers(struct device *dev, void *data) | |||
2215 | struct hid_device *hdev = to_hid_device(dev); | 2217 | struct hid_device *hdev = to_hid_device(dev); |
2216 | 2218 | ||
2217 | if (hdev->driver == hdrv && | 2219 | if (hdev->driver == hdrv && |
2218 | !hdrv->match(hdev, hid_ignore_special_drivers)) | 2220 | !hdrv->match(hdev, hid_ignore_special_drivers) && |
2221 | !test_and_set_bit(ffs(HID_STAT_REPROBED), &hdev->status)) | ||
2219 | return device_reprobe(dev); | 2222 | return device_reprobe(dev); |
2220 | 2223 | ||
2221 | return 0; | 2224 | return 0; |
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index 8469b6964ff6..b48100236df8 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c | |||
@@ -1154,6 +1154,8 @@ copy_rest: | |||
1154 | goto out; | 1154 | goto out; |
1155 | if (list->tail > list->head) { | 1155 | if (list->tail > list->head) { |
1156 | len = list->tail - list->head; | 1156 | len = list->tail - list->head; |
1157 | if (len > count) | ||
1158 | len = count; | ||
1157 | 1159 | ||
1158 | if (copy_to_user(buffer + ret, &list->hid_debug_buf[list->head], len)) { | 1160 | if (copy_to_user(buffer + ret, &list->hid_debug_buf[list->head], len)) { |
1159 | ret = -EFAULT; | 1161 | ret = -EFAULT; |
@@ -1163,6 +1165,8 @@ copy_rest: | |||
1163 | list->head += len; | 1165 | list->head += len; |
1164 | } else { | 1166 | } else { |
1165 | len = HID_DEBUG_BUFSIZE - list->head; | 1167 | len = HID_DEBUG_BUFSIZE - list->head; |
1168 | if (len > count) | ||
1169 | len = count; | ||
1166 | 1170 | ||
1167 | if (copy_to_user(buffer, &list->hid_debug_buf[list->head], len)) { | 1171 | if (copy_to_user(buffer, &list->hid_debug_buf[list->head], len)) { |
1168 | ret = -EFAULT; | 1172 | ret = -EFAULT; |
@@ -1170,7 +1174,9 @@ copy_rest: | |||
1170 | } | 1174 | } |
1171 | list->head = 0; | 1175 | list->head = 0; |
1172 | ret += len; | 1176 | ret += len; |
1173 | goto copy_rest; | 1177 | count -= len; |
1178 | if (count > 0) | ||
1179 | goto copy_rest; | ||
1174 | } | 1180 | } |
1175 | 1181 | ||
1176 | } | 1182 | } |
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index c1652bb7bd15..eae0cb3ddec6 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
@@ -484,7 +484,7 @@ static void i2c_hid_get_input(struct i2c_hid *ihid) | |||
484 | return; | 484 | return; |
485 | } | 485 | } |
486 | 486 | ||
487 | if ((ret_size > size) || (ret_size <= 2)) { | 487 | if ((ret_size > size) || (ret_size < 2)) { |
488 | dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", | 488 | dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", |
489 | __func__, size, ret_size); | 489 | __func__, size, ret_size); |
490 | return; | 490 | return; |
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index e3ce233f8bdc..23872d08308c 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/hiddev.h> | 36 | #include <linux/hiddev.h> |
37 | #include <linux/compat.h> | 37 | #include <linux/compat.h> |
38 | #include <linux/vmalloc.h> | 38 | #include <linux/vmalloc.h> |
39 | #include <linux/nospec.h> | ||
39 | #include "usbhid.h" | 40 | #include "usbhid.h" |
40 | 41 | ||
41 | #ifdef CONFIG_USB_DYNAMIC_MINORS | 42 | #ifdef CONFIG_USB_DYNAMIC_MINORS |
@@ -469,10 +470,14 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, | |||
469 | 470 | ||
470 | if (uref->field_index >= report->maxfield) | 471 | if (uref->field_index >= report->maxfield) |
471 | goto inval; | 472 | goto inval; |
473 | uref->field_index = array_index_nospec(uref->field_index, | ||
474 | report->maxfield); | ||
472 | 475 | ||
473 | field = report->field[uref->field_index]; | 476 | field = report->field[uref->field_index]; |
474 | if (uref->usage_index >= field->maxusage) | 477 | if (uref->usage_index >= field->maxusage) |
475 | goto inval; | 478 | goto inval; |
479 | uref->usage_index = array_index_nospec(uref->usage_index, | ||
480 | field->maxusage); | ||
476 | 481 | ||
477 | uref->usage_code = field->usage[uref->usage_index].hid; | 482 | uref->usage_code = field->usage[uref->usage_index].hid; |
478 | 483 | ||
@@ -499,6 +504,8 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, | |||
499 | 504 | ||
500 | if (uref->field_index >= report->maxfield) | 505 | if (uref->field_index >= report->maxfield) |
501 | goto inval; | 506 | goto inval; |
507 | uref->field_index = array_index_nospec(uref->field_index, | ||
508 | report->maxfield); | ||
502 | 509 | ||
503 | field = report->field[uref->field_index]; | 510 | field = report->field[uref->field_index]; |
504 | 511 | ||
@@ -753,6 +760,8 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
753 | 760 | ||
754 | if (finfo.field_index >= report->maxfield) | 761 | if (finfo.field_index >= report->maxfield) |
755 | break; | 762 | break; |
763 | finfo.field_index = array_index_nospec(finfo.field_index, | ||
764 | report->maxfield); | ||
756 | 765 | ||
757 | field = report->field[finfo.field_index]; | 766 | field = report->field[finfo.field_index]; |
758 | memset(&finfo, 0, sizeof(finfo)); | 767 | memset(&finfo, 0, sizeof(finfo)); |
@@ -797,6 +806,8 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
797 | 806 | ||
798 | if (cinfo.index >= hid->maxcollection) | 807 | if (cinfo.index >= hid->maxcollection) |
799 | break; | 808 | break; |
809 | cinfo.index = array_index_nospec(cinfo.index, | ||
810 | hid->maxcollection); | ||
800 | 811 | ||
801 | cinfo.type = hid->collection[cinfo.index].type; | 812 | cinfo.type = hid->collection[cinfo.index].type; |
802 | cinfo.usage = hid->collection[cinfo.index].usage; | 813 | cinfo.usage = hid->collection[cinfo.index].usage; |
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 0bb44d0088ed..ad7afa74d365 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
@@ -3365,8 +3365,14 @@ void wacom_setup_device_quirks(struct wacom *wacom) | |||
3365 | if (features->type >= INTUOSHT && features->type <= BAMBOO_PT) | 3365 | if (features->type >= INTUOSHT && features->type <= BAMBOO_PT) |
3366 | features->device_type |= WACOM_DEVICETYPE_PAD; | 3366 | features->device_type |= WACOM_DEVICETYPE_PAD; |
3367 | 3367 | ||
3368 | features->x_max = 4096; | 3368 | if (features->type == INTUOSHT2) { |
3369 | features->y_max = 4096; | 3369 | features->x_max = features->x_max / 10; |
3370 | features->y_max = features->y_max / 10; | ||
3371 | } | ||
3372 | else { | ||
3373 | features->x_max = 4096; | ||
3374 | features->y_max = 4096; | ||
3375 | } | ||
3370 | } | 3376 | } |
3371 | else if (features->pktlen == WACOM_PKGLEN_BBTOUCH) { | 3377 | else if (features->pktlen == WACOM_PKGLEN_BBTOUCH) { |
3372 | features->device_type |= WACOM_DEVICETYPE_PAD; | 3378 | features->device_type |= WACOM_DEVICETYPE_PAD; |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 41a3d5775394..773bcb1d4044 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -511,6 +511,7 @@ struct hid_output_fifo { | |||
511 | #define HID_STAT_ADDED BIT(0) | 511 | #define HID_STAT_ADDED BIT(0) |
512 | #define HID_STAT_PARSED BIT(1) | 512 | #define HID_STAT_PARSED BIT(1) |
513 | #define HID_STAT_DUP_DETECTED BIT(2) | 513 | #define HID_STAT_DUP_DETECTED BIT(2) |
514 | #define HID_STAT_REPROBED BIT(3) | ||
514 | 515 | ||
515 | struct hid_input { | 516 | struct hid_input { |
516 | struct list_head list; | 517 | struct list_head list; |
@@ -579,7 +580,7 @@ struct hid_device { /* device report descriptor */ | |||
579 | bool battery_avoid_query; | 580 | bool battery_avoid_query; |
580 | #endif | 581 | #endif |
581 | 582 | ||
582 | unsigned int status; /* see STAT flags above */ | 583 | unsigned long status; /* see STAT flags above */ |
583 | unsigned claimed; /* Claimed by hidinput, hiddev? */ | 584 | unsigned claimed; /* Claimed by hidinput, hiddev? */ |
584 | unsigned quirks; /* Various quirks the device can pull on us */ | 585 | unsigned quirks; /* Various quirks the device can pull on us */ |
585 | bool io_started; /* If IO has started */ | 586 | bool io_started; /* If IO has started */ |