Message ID | 1517830418-2648-1-git-send-email-william.wu@rock-chips.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi William, On Mon, Feb 05, 2018 at 07:33:38PM +0800, William Wu wrote: > Refer to the USB 3.0 spec '9.6.7 SuperSpeed Endpoint Companion', > the companion descriptor follows the standard endpoint descriptor. > This descriptor is only defined for SuperSpeed endpoints. The > f_fs driver gets the address of the companion descriptor via > 'ds + USB_DT_ENDPOINT_SIZE', and actually, the ds variable is > a pointer to the struct usb_endpoint_descriptor, so the offset > of the companion descriptor which we get is USB_DT_ENDPOINT_SIZE * > sizeof(struct usb_endpoint_descriptor), the wrong offset is 63 > bytes. This cause out-of-bound with the following error log if > CONFIG_KASAN and CONFIG_SLUB_DEBUG is enabled on Rockchip RK3399 > Evaluation Board. > > android_work: sent uevent USB_STATE=CONNECTED > configfs-gadget gadget: super-speed config #1: b > ================================================================== > BUG: KASAN: slab-out-of-bounds in ffs_func_set_alt+0x230/0x398 > Read of size 1 at addr ffffffc0ce2d0b10 by task irq/224-dwc3/364 > Memory state around the buggy address: > ffffffc0ce2d0a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > ffffffc0ce2d0a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > >ffffffc0ce2d0b00: 00 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc > ^ > ffffffc0ce2d0b80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc > ffffffc0ce2d0c00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc > ================================================================== > Disabling lock debugging due to kernel taint > android_work: sent uevent USB_STATE=CONFIGURED > > This patch adds struct usb_endpoint_descriptor * -> u8 * type conversion > for ds variable, then we can get the correct address of comp_desc > with offset USB_DT_ENDPOINT_SIZE bytes. > > Signed-off-by: William Wu <william.wu@rock-chips.com> > --- > drivers/usb/gadget/function/f_fs.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c > index 6756472..f13ead0 100644 > --- a/drivers/usb/gadget/function/f_fs.c > +++ b/drivers/usb/gadget/function/f_fs.c > @@ -1882,8 +1882,8 @@ static int ffs_func_eps_enable(struct ffs_function *func) > ep->ep->desc = ds; > > if (needs_comp_desc) { > - comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds + > - USB_DT_ENDPOINT_SIZE); > + comp_desc = (struct usb_ss_ep_comp_descriptor *) > + ((u8 *)ds + USB_DT_ENDPOINT_SIZE); > ep->ep->maxburst = comp_desc->bMaxBurst + 1; > ep->ep->comp_desc = comp_desc; > } Please see my alternative fix for this. I proposed changing this function to use config_ep_by_speed() instead. https://www.spinics.net/lists/linux-usb/msg165149.html Jack
Hi Jack, 在 2018年02月06日 02:17, Jack Pham 写道: > Hi William, > > On Mon, Feb 05, 2018 at 07:33:38PM +0800, William Wu wrote: >> Refer to the USB 3.0 spec '9.6.7 SuperSpeed Endpoint Companion', >> the companion descriptor follows the standard endpoint descriptor. >> This descriptor is only defined for SuperSpeed endpoints. The >> f_fs driver gets the address of the companion descriptor via >> 'ds + USB_DT_ENDPOINT_SIZE', and actually, the ds variable is >> a pointer to the struct usb_endpoint_descriptor, so the offset >> of the companion descriptor which we get is USB_DT_ENDPOINT_SIZE * >> sizeof(struct usb_endpoint_descriptor), the wrong offset is 63 >> bytes. This cause out-of-bound with the following error log if >> CONFIG_KASAN and CONFIG_SLUB_DEBUG is enabled on Rockchip RK3399 >> Evaluation Board. >> >> android_work: sent uevent USB_STATE=CONNECTED >> configfs-gadget gadget: super-speed config #1: b >> ================================================================== >> BUG: KASAN: slab-out-of-bounds in ffs_func_set_alt+0x230/0x398 >> Read of size 1 at addr ffffffc0ce2d0b10 by task irq/224-dwc3/364 >> Memory state around the buggy address: >> ffffffc0ce2d0a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> ffffffc0ce2d0a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> >ffffffc0ce2d0b00: 00 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc >> ^ >> ffffffc0ce2d0b80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc >> ffffffc0ce2d0c00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc >> ================================================================== >> Disabling lock debugging due to kernel taint >> android_work: sent uevent USB_STATE=CONFIGURED >> >> This patch adds struct usb_endpoint_descriptor * -> u8 * type conversion >> for ds variable, then we can get the correct address of comp_desc >> with offset USB_DT_ENDPOINT_SIZE bytes. >> >> Signed-off-by: William Wu <william.wu@rock-chips.com> >> --- >> drivers/usb/gadget/function/f_fs.c | 4 ++-- >> 1 file changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c >> index 6756472..f13ead0 100644 >> --- a/drivers/usb/gadget/function/f_fs.c >> +++ b/drivers/usb/gadget/function/f_fs.c >> @@ -1882,8 +1882,8 @@ static int ffs_func_eps_enable(struct ffs_function *func) >> ep->ep->desc = ds; >> >> if (needs_comp_desc) { >> - comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds + >> - USB_DT_ENDPOINT_SIZE); >> + comp_desc = (struct usb_ss_ep_comp_descriptor *) >> + ((u8 *)ds + USB_DT_ENDPOINT_SIZE); >> ep->ep->maxburst = comp_desc->bMaxBurst + 1; >> ep->ep->comp_desc = comp_desc; >> } > Please see my alternative fix for this. I proposed changing this > function to use config_ep_by_speed() instead. > > https://www.spinics.net/lists/linux-usb/msg165149.html Thanks for your great job! Your patch seems good, I will test your patch on my RK3399-EVB board. William > > Jack
================================================================== BUG: KASAN: slab-out-of-bounds in ffs_func_set_alt+0x230/0x398 Read of size 1 at addr ffffffc0ce2d0b10 by task irq/224-dwc3/364 CPU: 4 PID: 364 Comm: irq/224-dwc3 Not tainted 4.4.112 #6 Hardware name: Rockchip RK3399 Evaluation Board v3 (Android) (DT) Call trace: [<ffffff900808c4a4>] dump_backtrace+0x0/0x244 [<ffffff900808c6fc>] show_stack+0x14/0x1c [<ffffff90084f0ff4>] dump_stack+0xa4/0xcc [<ffffff900822d054>] print_address_description+0xa4/0x308 [<ffffff900822d5bc>] kasan_report+0x258/0x29c [<ffffff900822bb28>] __asan_load1+0x44/0x4c [<ffffff9008b6eec4>] ffs_func_set_alt+0x230/0x398 [<ffffff9008b56e5c>] composite_setup+0xdcc/0x1ac8 [<ffffff9008b5aaa4>] android_setup+0x124/0x1a0 [<ffffff9008aa22b4>] dwc3_ep0_delegate_req+0x48/0x68 [<ffffff9008aa3248>] dwc3_ep0_interrupt+0x758/0x1174 [<ffffff9008a9f688>] dwc3_thread_interrupt+0x204/0xe68 [<ffffff9008126c04>] irq_thread_fn+0x44/0x94 [<ffffff9008126e44>] irq_thread+0x128/0x22c [<ffffff90080d39c4>] kthread+0x11c/0x130 [<ffffff90080832a0>] ret_from_fork+0x10/0x30 Allocated by task 1: [<ffffff900808bf0c>] save_stack_trace_tsk+0x0/0x134 [<ffffff900808c054>] save_stack_trace+0x14/0x1c [<ffffff900822c188>] kasan_kmalloc.part.3+0x48/0xf4 [<ffffff900822c3c8>] kasan_kmalloc+0x8c/0xa0 [<ffffff9008229990>] __kmalloc+0x208/0x268 [<ffffff9008b71258>] ffs_func_bind+0x4b4/0x918 [<ffffff9008b55168>] usb_add_function+0xd8/0x1d4 [<ffffff9008b5b204>] configfs_composite_bind+0x48c/0x570 [<ffffff9008b5dc80>] udc_bind_to_driver+0x6c/0x170 [<ffffff9008b5de28>] usb_udc_attach_driver+0xa4/0xd0 [<ffffff9008b5c110>] gadget_dev_desc_UDC_store+0xd4/0x120 [<ffffff90082d6014>] configfs_write_file+0x1a0/0x1f8 [<ffffff9008237960>] __vfs_write+0x64/0x174 [<ffffff9008238560>] vfs_write+0xe4/0x1e8 [<ffffff90082392fc>] SyS_write+0x68/0xc8 [<ffffff90080832f0>] el0_svc_naked+0x24/0x28 Freed by task 0: (stack is not available) The buggy address belongs to the object at ffffffc0ce2d0900 which belongs to the cache kmalloc-1024 of size 1024 The buggy address is located 528 bytes inside of 1024-byte region [ffffffc0ce2d0900, ffffffc0ce2d0d00) The buggy address belongs to the page: page:ffffffbdc338b400 count:1 mapcount:-2145648611 mapping: (null) index:0x0 flags: 0x4080(slab|head) page dumped because: kasan: bad access detected Memory state around the buggy address: ffffffc0ce2d0a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffffffc0ce2d0a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >ffffffc0ce2d0b00: 00 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc ^ ffffffc0ce2d0b80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffffffc0ce2d0c00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ================================================================== Disabling lock debugging due to kernel taint android_work: sent uevent USB_STATE=CONFIGURED This patch adds struct usb_endpoint_descriptor * -> u8 * type conversion for ds variable, then we can get the correct address of comp_desc with offset USB_DT_ENDPOINT_SIZE bytes. Signed-off-by: William Wu <william.wu@rock-chips.com> --- drivers/usb/gadget/function/f_fs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 6756472..f13ead0 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1882,8 +1882,8 @@ static int ffs_func_eps_enable(struct ffs_function *func) ep->ep->desc = ds; if (needs_comp_desc) { - comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds + - USB_DT_ENDPOINT_SIZE); + comp_desc = (struct usb_ss_ep_comp_descriptor *) + ((u8 *)ds + USB_DT_ENDPOINT_SIZE); ep->ep->maxburst = comp_desc->bMaxBurst + 1; ep->ep->comp_desc = comp_desc; }