Hi,

there are multiple bugs in current (2.5.56) hiddev.c:

1. hiddev_ioctl(): in the big switch(), several cases simply fall through
   to the next case. Obviously, the final return 0 is missing.

2. HIDIOCAPPLICATION: hid->collection[i].usage might be negative. This
   causes the ioctl() ti return -1 and errno containing the desired
   result:

   I.e. (tested on Alpha):

   ioctl(3, 0x20004802, 0)                 = -1 E??? (errno 6291455)

   hid->collection[i].usage is 0xffa00001 in this case

   Report Descriptor: (length is 48)
   Item(Global): Usage Page, data= [ 0xa0 0xff ] 65440
   Item(Local ): Usage, data= [ 0x01 ] 1

3. HIDIOCGUSAGE, HIDIOCSUSAGE don't allow to access field index > 0
   when there is only 1 usage and 1 field but report count > 1.
   Obviously, the only way from user space to select the index is
   using uref.usage_index. I guess, this should be chacked against
   field->report_count rather than field->maxusage.

This patch attempts to fix issues 2 and 3.

--jochen

===== hiddev.c 1.26 vs edited =====
--- 1.26/drivers/usb/input/hiddev.c     Tue Dec  3 02:09:46 2002
+++ edited/hiddev.c     Sun Jan 12 19:02:33 2003
@@ -436,10 +436,12 @@
                dinfo.num_applications = hid->maxapplication;
                if (copy_to_user((void *) arg, &dinfo, sizeof(dinfo)))
                        return -EFAULT;
+               return 0;

        case HIDIOCGFLAG:
                if (put_user(list->flags, (int *) arg))
                        return -EFAULT;
+               return 0;

        case HIDIOCSFLAG:
                {
@@ -456,6 +458,7 @@

                        return 0;
                }
+               return 0;

        case HIDIOCGSTRING:
                {
@@ -482,6 +485,7 @@

                        return len;
                }
+               return 0;

        case HIDIOCINITREPORT:
                hid_init_reports(hid);
@@ -527,6 +531,7 @@

                if (copy_to_user((void *) arg, &rinfo, sizeof(rinfo)))
                        return -EFAULT;
+               return 0;

        case HIDIOCGFIELDINFO:
                if (copy_from_user(&finfo, (void *) arg, sizeof(finfo)))
@@ -558,6 +563,7 @@

                if (copy_to_user((void *) arg, &finfo, sizeof(finfo)))
                        return -EFAULT;
+               return 0;

        case HIDIOCGUCODE:
                if (copy_from_user(&uref, (void *) arg, sizeof(uref)))
@@ -579,6 +585,7 @@

                if (copy_to_user((void *) arg, &uref, sizeof(uref)))
                        return -EFAULT;
+               return 0;

        case HIDIOCGUSAGE:
        case HIDIOCSUSAGE:
@@ -603,7 +610,7 @@
                                return -EINVAL;

                        field = report->field[uref.field_index];
-                       if (uref.usage_index >= field->maxusage)
+                       if (uref.usage_index > field->report_count)
                                return -EINVAL;
                }






-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to