DF-5604 / fix.diff
--- sys/bus/u4b/usb_util.c +++ sys/bus/u4b/usb_util.c @@ -66,6 +66,7 @@ struct usb_attach_arg *uaa; struct usb_device *udev; struct usb_interface *iface; + char buf[256]; /* stable snapshot of scratch string */ char *temp_p; usb_error_t err; uint8_t do_unlock; @@ -108,11 +109,20 @@ sizeof(udev->scratch.data)); } + /* + * Snapshot the string while the enumeration lock is still held: + * udev->scratch is shared by every enumeration path of this udev and + * is only valid while the lock is owned. Using it after the unlock + * allows a concurrent usbd_req_get_string_any() to clobber the NUL + * terminator, which makes the strlen()/strcpy() in + * device_set_desc_copy() walk past the end of the scratch buffer. + */ + bcopy(temp_p, buf, sizeof(udev->scratch.data)); + buf[sizeof(buf) - 1] = '\0'; + if (do_unlock) usbd_enum_unlock(udev); - device_set_desc_copy(dev, temp_p); - device_printf(dev, "<%s> on %s\n", temp_p, + device_set_desc_copy(dev, buf); + device_printf(dev, "<%s> on %s\n", buf, device_get_nameunit(udev->bus->bdev)); } |