mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-16 07:24:39 +08:00
usb: gadget: f_ecm: Always set current gadget in ecm_bind()
The gadget may change over bind/unbind cycles, so set it each time during bind, not only the first time. Without it we get a use-after-free with the following example: cd /sys/kernel/config/usb_gadget/; mkdir -p mygadget; cd mygadget mkdir -p configs/c.1/strings/0x409 echo "C1:Composite Device" > configs/c.1/strings/0x409/configuration mkdir -p functions/ecm.usb0 ln -s functions/ecm.usb0 configs/c.1/ rmmod dummy_hcd modprobe dummy_hcd KASAN will complain shortly after the 'modprobe': usb 2-1: New USB device found, idVendor=0000, idProduct=0000, bcdDevice= 6.01 usb 2-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0 ================================================================== BUG: KASAN: use-after-free in gether_connect+0xb8/0x30c Read of size 4 at addr cbef170c by task swapper/3/0 CPU: 3 PID: 0 Comm: swapper/3 Not tainted 6.1.0-rc3-00014-g41ff012f50cb-dirty #322 Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) unwind_backtrace from show_stack+0x10/0x14 show_stack from dump_stack_lvl+0x58/0x70 dump_stack_lvl from print_report+0x134/0x4d4 print_report from kasan_report+0x78/0x10c kasan_report from gether_connect+0xb8/0x30c gether_connect from ecm_set_alt+0x124/0x254 ecm_set_alt from composite_setup+0xb98/0x2b18 composite_setup from configfs_composite_setup+0x80/0x98 configfs_composite_setup from dummy_timer+0x8f0/0x14a0 [dummy_hcd] ... Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Link: https://lore.kernel.org/r/20221104131031.850850-3-s.hauer@pengutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
321b59870f
commit
d65e6b6e88
@ -685,7 +685,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
struct usb_composite_dev *cdev = c->cdev;
|
||||
struct f_ecm *ecm = func_to_ecm(f);
|
||||
struct usb_string *us;
|
||||
int status;
|
||||
int status = 0;
|
||||
struct usb_ep *ep;
|
||||
|
||||
struct f_ecm_opts *ecm_opts;
|
||||
@ -695,23 +695,19 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
|
||||
ecm_opts = container_of(f->fi, struct f_ecm_opts, func_inst);
|
||||
|
||||
/*
|
||||
* in drivers/usb/gadget/configfs.c:configfs_composite_bind()
|
||||
* configurations are bound in sequence with list_for_each_entry,
|
||||
* in each configuration its functions are bound in sequence
|
||||
* with list_for_each_entry, so we assume no race condition
|
||||
* with regard to ecm_opts->bound access
|
||||
*/
|
||||
mutex_lock(&ecm_opts->lock);
|
||||
|
||||
gether_set_gadget(ecm_opts->net, cdev->gadget);
|
||||
|
||||
if (!ecm_opts->bound) {
|
||||
mutex_lock(&ecm_opts->lock);
|
||||
gether_set_gadget(ecm_opts->net, cdev->gadget);
|
||||
status = gether_register_netdev(ecm_opts->net);
|
||||
mutex_unlock(&ecm_opts->lock);
|
||||
if (status)
|
||||
return status;
|
||||
ecm_opts->bound = true;
|
||||
}
|
||||
|
||||
mutex_unlock(&ecm_opts->lock);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
ecm_string_defs[1].s = ecm->ethaddr;
|
||||
|
||||
us = usb_gstrings_attach(cdev, ecm_strings,
|
||||
|
Loading…
Reference in New Issue
Block a user