On Wed, 14 Apr 2004 20:22:17 +1000
Herbert Xu <[EMAIL PROTECTED]> wrote:

> The current code is applying the maxusage limit to GUSAGE/SUSAGE.  This
> is incorrect as the number of values is stored in field->report_count,
> not field->maxusage.  The USB phone from www.virbiage.com is one device
> where report_count exceeds maxusage.
> 
> The following patch corrects the check for 2.6.

Whatever has come out of this? It's not in Linus' tree as of a minute ago.
Is this something Greg can bless, or we need Vojtech's nod?

-- Pete

--- a/drivers/usb/input/hiddev.c        5 Apr 2004 09:49:36 -0000       1.1.1.12
+++ b/drivers/usb/input/hiddev.c        14 Apr 2004 10:07:25 -0000
@@ -575,33 +575,11 @@
 
                return 0;
 
-       case HIDIOCGUCODE:
-               if (copy_from_user(uref, (void *) arg, sizeof(*uref)))
-                       return -EFAULT;
-
-               rinfo.report_type = uref->report_type;
-               rinfo.report_id = uref->report_id;
-               if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
-                       return -EINVAL;
-
-               if (uref->field_index >= report->maxfield)
-                       return -EINVAL;
-
-               field = report->field[uref->field_index];
-               if (uref->usage_index >= field->maxusage)
-                       return -EINVAL;
-
-               uref->usage_code = field->usage[uref->usage_index].hid;
-
-               if (copy_to_user((void *) arg, uref, sizeof(*uref)))
-                       return -EFAULT;
-
-               return 0;
-
        case HIDIOCGUSAGE:
        case HIDIOCSUSAGE:
        case HIDIOCGUSAGES:
        case HIDIOCSUSAGES:
+       case HIDIOCGUCODE:
        case HIDIOCGCOLLECTIONINDEX:
                if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
                        if (copy_from_user(&uref_multi, (void *) arg, 
@@ -617,7 +595,8 @@
                    uref->report_type == HID_REPORT_TYPE_INPUT)
                        return -EINVAL;
 
-               if (uref->report_id == HID_REPORT_ID_UNKNOWN) {
+               if (cmd != HIDIOCGUCODE &&
+                   uref->report_id == HID_REPORT_ID_UNKNOWN) {
                        field = hiddev_lookup_usage(hid, uref);
                        if (field == NULL)
                                return -EINVAL;
@@ -631,28 +610,34 @@
                                return -EINVAL;
 
                        field = report->field[uref->field_index];
-                       if (uref->usage_index >= field->maxusage)
-                               return -EINVAL;
-
-                       if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
-                               if (uref_multi.num_values >= HID_MAX_USAGES || 
-                                   uref->usage_index >= field->maxusage || 
-                                  (uref->usage_index + uref_multi.num_values) >= 
field->maxusage)
+                       if (cmd == HIDIOCGUCODE ||
+                           cmd == HIDIOCGCOLLECTIONINDEX) {
+                               if (uref->usage_index >= field->maxusage)
                                        return -EINVAL;
-                       }
+                       } else if (uref->usage_index >= field->report_count)
+                               return -EINVAL;
+                       else if ((cmd == HIDIOCGUSAGES ||
+                                 cmd == HIDIOCSUSAGES) &&
+                                (uref->usage_index + uref_multi.num_values >=
+                                 field->report_count ||
+                                 uref->usage_index + uref_multi.num_values <
+                                 uref->usage_index))
+                               return -EINVAL;
                }
 
                switch (cmd) {
                        case HIDIOCGUSAGE:
                                uref->value = field->value[uref->usage_index];
-                               if (copy_to_user((void *) arg, uref, sizeof(*uref)))
-                                       return -EFAULT;
-                               return 0;
+                               break;
 
                        case HIDIOCSUSAGE:
                                field->value[uref->usage_index] = uref->value;
                                return 0;
 
+                       case HIDIOCGUCODE:
+                               uref->usage_code = field->usage[uref->usage_index].hid;
+                               break;
+
                        case HIDIOCGCOLLECTIONINDEX:
                                return 
field->usage[uref->usage_index].collection_index;
                        case HIDIOCGUSAGES:
@@ -670,6 +655,8 @@
                                return 0;
                }
 
+               if (copy_to_user((void *) arg, uref, sizeof(*uref)))
+                       return -EFAULT;
                return 0;
 
        case HIDIOCGCOLLECTIONINFO:


-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to