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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html