Patch "usb: gadget: f_fs: Use config_ep_by_speed()" has been added to the 4.15-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
usb: gadget: f_fs: Use config_ep_by_speed()
to the 4.15-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
usb-gadget-f_fs-use-config_ep_by_speed.patch
and it can be found in the queue-4.15 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
675272d092e4a5570bace92593776f7348daf4c5Mon Sep 17 00:00:00 2001
From: Jack Pham <[email protected]>
Date: Wed, 24 Jan 2018 23:58:20 -0800
Subject: usb: gadget: f_fs: Use config_ep_by_speed()
From: Jack Pham <[email protected]>
commit 675272d092e4a5570bace92593776f7348daf4c5 upstream.
In commit 2bfa0719ac2a ("usb: gadget: function: f_fs: pass companion descriptor along") there is a pointer arithmetic bug where the comp_desc is obtained as follows:
comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds +
USB_DT_ENDPOINT_SIZE);
Since ds is a pointer to usb_endpoint_descriptor, adding 7 to it ends up going out of bounds (7 * sizeof(struct usb_endpoint_descriptor), which is actually 7*9 bytes) past the SS descriptor. As a result the maxburst value will be read incorrectly, and the UDC driver will also get a garbage comp_desc (assuming it uses it).
Since Felipe wrote, "Eventually, f_fs.c should be converted to use config_ep_by_speed() like all other functions, though", let's finally do it. This allows the other usb_ep fields to be properly populated, such as maxpacket and mult. It also eliminates the awkward speed-based descriptor lookup since config_ep_by_speed() does that already using the ones found in struct usb_function.
--- drivers/usb/gadget/function/f_fs.c | 38 ++++++------------------------------- 1 file changed, 7 insertions(+), 31 deletions(-)
drivers/usb/gadget/function/f_fs.c +7 -31
@@ -1852,44 +1852,20 @@ static int ffs_func_eps_enable(struct ffspin_lock_irqsave (&func->ffs->eps_lock, flags);while (count--) { -struct usb_endpoint_descriptor *ds; -struct usb_ss_ep_comp_descriptor *comp_desc =NULL ; -int needs_comp_desc = false; -int desc_idx; - -if (ffs->gadget->speed ==USB_SPEED_SUPER ) { - desc_idx =2 ; - needs_comp_desc = true; - }else if (ffs->gadget->speed ==USB_SPEED_HIGH ) - desc_idx =1 ; -else - desc_idx =0 ; - -/* fall-back to lower speed if desc missing for current speed */ -do { - ds = ep->descs[desc_idx]; - }while (!ds && --desc_idx >=0 ); - -if (!ds) { - ret = -EINVAL ; -break ; - } - ep->ep->driver_data = ep; - ep->ep->desc = ds; -if (needs_comp_desc) { - comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds + -USB_DT_ENDPOINT_SIZE ); - ep->ep->maxburst = comp_desc->bMaxBurst +1 ; - ep->ep->comp_desc = comp_desc; + ret =config_ep_by_speed (func->gadget, &func->function, ep->ep); +if (ret) { +pr_err ("%s: config_ep_by_speed(%s) returned %d\n" , + __func__, ep->ep->name, ret); +break ; } ret =usb_ep_enable (ep->ep);if (likely (!ret)) { epfile->ep = ep; - epfile->in =usb_endpoint_dir_in (ds); - epfile->isoc =usb_endpoint_xfer_isoc (ds); + epfile->in =usb_endpoint_dir_in (ep->ep->desc); + epfile->isoc =usb_endpoint_xfer_isoc (ep->ep->desc); }else {break ; }
Patches currently in stable-queue which might be from [email protected] are
queue-4.15/usb-gadget-f_fs-use-config_ep_by_speed.patch queue-4.15/usb-gadget-f_fs-process-all-descriptors-during-bind.patch