aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2025-01-03 09:50:30 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2025-01-07 09:03:21 +0000
commiteb9fa4c2d786b327bb4d9bd7727428c70a33c710 (patch)
tree3ce3aec37b0135c5344bdcd5b0c3b2351597bca4
parent014064b33f72c4405117eb71e6a06c8b51cc224e (diff)
libusb: fix hotplug sigbus
When a hotplug callback has been registered, and the program using libusb is calling libusb_exit then the thread handler is set to NO_THREAD which result in the variable controlling the loop the be set to 0, it does a last pass through device available without having done a scan, which result in a sigbus after it tried to unregister all the devices. directly break the loop instead and cleanup the list of devices this fixes the tests with LGPLed libusb's hotplugtest program MFC After: 3 days Reviewed by: kevans Differential Revision: https://reviews.freebsd.org/D48298 (cherry picked from commit ba5834b8e11fd002a663d083a464e397e76cb3a9)
-rw-r--r--lib/libusb/libusb10_hotplug.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/lib/libusb/libusb10_hotplug.c b/lib/libusb/libusb10_hotplug.c
index 9d00b1dbe5a0..98903686f76b 100644
--- a/lib/libusb/libusb10_hotplug.c
+++ b/lib/libusb/libusb10_hotplug.c
@@ -112,22 +112,25 @@ libusb_hotplug_scan(void *arg)
libusb_device *temp;
libusb_device *adev;
libusb_device *bdev;
- unsigned do_loop = 1;
- while (do_loop) {
+ for (;;) {
usleep(4000000);
HOTPLUG_LOCK(ctx);
+ if (ctx->hotplug_handler == NO_THREAD) {
+ while ((adev = TAILQ_FIRST(&ctx->hotplug_devs)) != NULL) {
+ TAILQ_REMOVE(&ctx->hotplug_devs, adev, hotplug_entry);
+ libusb_unref_device(adev);
+ }
+ HOTPLUG_UNLOCK(ctx);
+ break;
+ }
TAILQ_INIT(&hotplug_devs);
- if (ctx->hotplug_handler != NO_THREAD) {
- if (libusb_hotplug_enumerate(ctx, &hotplug_devs) < 0) {
- HOTPLUG_UNLOCK(ctx);
- continue;
- }
- } else {
- do_loop = 0;
+ if (libusb_hotplug_enumerate(ctx, &hotplug_devs) < 0) {
+ HOTPLUG_UNLOCK(ctx);
+ continue;
}
/* figure out which devices are gone */