The USB device descriptor may get changed between two consecutive enumerations on the same device for some reason, such as DFU or malicius device. In that case, we may access the changing descriptor if we don't take the device lock here.
The issue is reported: https://syzkaller.appspot.com/bug?id=901a0d9e6519ef8dc7acab25344bd287dd3c7be...
Cc: stable stable@vger.kernel.org Cc: Alan Stern stern@rowland.harvard.edu Reported-by: syzbot+256e56ddde8b8957eabd@syzkaller.appspotmail.com Fixes: 217a9081d8e6 ("USB: add all configs to the "descriptors" attribute") Signed-off-by: Zeng Tao prime.zeng@hisilicon.com --- drivers/usb/core/sysfs.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index a2ca38e..8d13419 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -889,7 +889,11 @@ read_descriptors(struct file *filp, struct kobject *kobj, size_t srclen, n; int cfgno; void *src; + int retval;
+ retval = usb_lock_device_interruptible(udev); + if (retval < 0) + return -EINTR; /* The binary attribute begins with the device descriptor. * Following that are the raw descriptor entries for all the * configurations (config plus subsidiary descriptors). @@ -914,6 +918,7 @@ read_descriptors(struct file *filp, struct kobject *kobj, off -= srclen; } } + usb_unlock_device(udev); return count - nleft; }