On Fri, 4 Oct 2013, Hans de Goede wrote:

> +static int parse_usbdevfs_streams(struct usb_device *dev,
> +                               struct usbdevfs_streams __user *streams,
> +                               unsigned int *num_streams_ret,
> +                               unsigned int *num_eps_ret,
> +                               struct usb_host_endpoint ***eps_ret,
> +                               struct usb_interface **intf_ret)
> +{
> +     unsigned int i, num_streams, num_eps;
> +     struct usb_host_endpoint **eps;
> +     struct usb_interface *intf = NULL;
> +     unsigned char ep;
> +     int ret;
> +
> +     if (get_user(num_streams, &streams->num_streams) ||
> +         get_user(num_eps, &streams->num_eps))
> +             return -EFAULT;
> +
> +     if (num_eps < 1 || num_eps > USB_MAXENDPOINTS)
> +             return -EINVAL;
> +
> +     /* The XHCI controller allows max 1024 streams */
> +     if (num_streams_ret && (num_streams < 2 || num_streams > 1024))
> +             return -EINVAL;
> +
> +     eps = kmalloc(num_eps * sizeof(*eps), GFP_KERNEL);
> +     if (!eps)
> +             return -ENOMEM;
> +
> +     for (i = 0; i < num_eps; i++) {
> +             if (get_user(ep, &streams->eps[i])) {
> +                     ret = -EFAULT;
> +                     goto error;
> +             }
> +             eps[i] = ep_to_host_endpoint(dev, ep);
> +             if (!eps[i]) {
> +                     ret = -EINVAL;
> +                     goto error;
> +             }
> +
> +             /* usb_alloc/free_streams operate on an usb_interface */
> +             ret = findintfep(dev, ep);
> +             if (ret < 0)
> +                     goto error;
> +
> +             if (i == 0) {
> +                     intf = usb_ifnum_to_if(dev, ret);
> +             } else {
> +                     /* Verify all eps belong to the same interface */
> +                     if (ret != intf->altsetting->desc.bInterfaceNumber) {
> +                             ret = -EINVAL;
> +                             goto error;
> +                     }
> +             }
> +     }
> +
> +     if (num_streams_ret)
> +             *num_streams_ret = num_streams;
> +     *num_eps_ret = num_eps;
> +     *eps_ret = eps;
> +     *intf_ret = intf;
> +
> +     return 0;
> +
> +error:
> +     kfree(eps);
> +     return ret;
> +}

Somewhere in here you should check that the caller has claimed the 
interface containing these endpoints.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to