diff options
| -rw-r--r-- | drivers/hid/usbhid/hiddev.c | 11 |
1 files changed, 11 insertions, 0 deletions
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; |
