|
@@ -36,6 +36,7 @@
|
|
|
#include <linux/hiddev.h>
|
|
|
#include <linux/compat.h>
|
|
|
#include <linux/vmalloc.h>
|
|
|
+#include <linux/nospec.h>
|
|
|
#include "usbhid.h"
|
|
|
|
|
|
#ifdef CONFIG_USB_DYNAMIC_MINORS
|
|
@@ -469,10 +470,14 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
|
|
|
|
|
|
if (uref->field_index >= report->maxfield)
|
|
|
goto inval;
|
|
|
+ uref->field_index = array_index_nospec(uref->field_index,
|
|
|
+ report->maxfield);
|
|
|
|
|
|
field = report->field[uref->field_index];
|
|
|
if (uref->usage_index >= field->maxusage)
|
|
|
goto inval;
|
|
|
+ uref->usage_index = array_index_nospec(uref->usage_index,
|
|
|
+ field->maxusage);
|
|
|
|
|
|
uref->usage_code = field->usage[uref->usage_index].hid;
|
|
|
|
|
@@ -499,6 +504,8 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
|
|
|
|
|
|
if (uref->field_index >= report->maxfield)
|
|
|
goto inval;
|
|
|
+ uref->field_index = array_index_nospec(uref->field_index,
|
|
|
+ report->maxfield);
|
|
|
|
|
|
field = report->field[uref->field_index];
|
|
|
|
|
@@ -753,6 +760,8 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|
|
|
|
|
if (finfo.field_index >= report->maxfield)
|
|
|
break;
|
|
|
+ finfo.field_index = array_index_nospec(finfo.field_index,
|
|
|
+ report->maxfield);
|
|
|
|
|
|
field = report->field[finfo.field_index];
|
|
|
memset(&finfo, 0, sizeof(finfo));
|
|
@@ -797,6 +806,8 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|
|
|
|
|
if (cinfo.index >= hid->maxcollection)
|
|
|
break;
|
|
|
+ cinfo.index = array_index_nospec(cinfo.index,
|
|
|
+ hid->maxcollection);
|
|
|
|
|
|
cinfo.type = hid->collection[cinfo.index].type;
|
|
|
cinfo.usage = hid->collection[cinfo.index].usage;
|