usb: gadget: composite: avoid kernel oops with bad gadgets
authorFelipe Balbi <felipe.balbi@linux.intel.com>
Fri, 22 Apr 2016 11:53:47 +0000 (14:53 +0300)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Thu, 28 Apr 2016 06:02:00 +0000 (09:02 +0300)
If a gadget driver loaded to a Superspeed-capable
peripheral controller, using a Superspeed cable,
doesn't provide Superspeed descriptors, we will get
a NULL pointer dereference.

In order to avoid that situation, we will try to
find any valid descriptors we can. If no set of
descriptors is passed in, then we'll let that gadget
oops anyhow.

Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/gadget/composite.c

index de9ffd60fcfa84b59291e755edc4ca0fb9945f2f..3d3cdc5ed20d1e64a7bce814d1d286c87ead5d92 100644 (file)
@@ -66,20 +66,36 @@ function_descriptors(struct usb_function *f,
 {
        struct usb_descriptor_header **descriptors;
 
+       /*
+        * NOTE: we try to help gadget drivers which might not be setting
+        * max_speed appropriately.
+        */
+
        switch (speed) {
        case USB_SPEED_SUPER_PLUS:
                descriptors = f->ssp_descriptors;
-               break;
+               if (descriptors)
+                       break;
+               /* FALLTHROUGH */
        case USB_SPEED_SUPER:
                descriptors = f->ss_descriptors;
-               break;
+               if (descriptors)
+                       break;
+               /* FALLTHROUGH */
        case USB_SPEED_HIGH:
                descriptors = f->hs_descriptors;
-               break;
+               if (descriptors)
+                       break;
+               /* FALLTHROUGH */
        default:
                descriptors = f->fs_descriptors;
        }
 
+       /*
+        * if we can't find any descriptors at all, then this gadget deserves to
+        * Oops with a NULL pointer dereference
+        */
+
        return descriptors;
 }