git: fc3e8434a61f - main - libusb: Fix NULL dereference when a hotplug callback deregisters itself
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 24 Aug 2026 01:30:02 UTC
The branch main has been updated by aokblast:
URL: https://cgit.FreeBSD.org/src/commit/?id=fc3e8434a61f372b4d6ec6bd8910ac8cd54b9b37
commit fc3e8434a61f372b4d6ec6bd8910ac8cd54b9b37
Author: yuvrajnode <yuvrajsinghrock1221@gmail.com>
AuthorDate: 2026-08-23 07:15:49 +0000
Commit: ShengYi Hung <aokblast@FreeBSD.org>
CommitDate: 2026-08-24 01:29:52 +0000
libusb: Fix NULL dereference when a hotplug callback deregisters itself
libusb_hotplug_register_callback() runs the newly registered callback
over the already-enumerated device list when LIBUSB_HOTPLUG_ENUMERATE
is set. A hotplug callback returning non-zero means "deregister me",
and the enumerate loop honours that by freeing the handle and setting
it to NULL.
Since commit 6bda9f26d2ed changed libusb_hotplug_callback_handle from a
pointer to an int, the tail of the function unconditionally dereferences
that handle, so any caller that passes LIBUSB_HOTPLUG_ENUMERATE, a
non-NULL handle pointer, and a callback that returns non-zero on a
matching device crashes inside libusb. This is a normal usage pattern
and it was safe before the conversion, when the equivalent line simply
stored NULL.
Report the reserved id 0 instead. The allocator hands out ids starting
at 1, and libusb_hotplug_deregister_callback() already ignores 0, so
this restores the pre-conversion behaviour.
Signed-off-by: yuvrajnode <yuvrajsinghrock1221@gmail.com>
Reviewed by: aokblast
Fixes: 6bda9f26d2ed ("libusb: change callback register handler to int")
Pull Request: https://github.com/freebsd/freebsd-src/pull/2383
Closes: https://github.com/freebsd/freebsd-src/pull/2383
---
lib/libusb/libusb10_hotplug.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/lib/libusb/libusb10_hotplug.c b/lib/libusb/libusb10_hotplug.c
index 5def972c5ab5..cf8eeafabc52 100644
--- a/lib/libusb/libusb10_hotplug.c
+++ b/lib/libusb/libusb10_hotplug.c
@@ -408,8 +408,15 @@ int libusb_hotplug_register_callback(libusb_context *ctx,
TAILQ_INSERT_TAIL(&ctx->hotplug_cbh, handle, entry);
HOTPLUG_UNLOCK(ctx);
+ /*
+ * The callback may have deregistered itself during the
+ * LIBUSB_HOTPLUG_ENUMERATE pass above, in which case handle is
+ * already freed. Report the reserved id 0, which is never handed
+ * out by the allocator above and which
+ * libusb_hotplug_deregister_callback() treats as a no-op.
+ */
if (phandle != NULL)
- *phandle = handle->id;
+ *phandle = (handle != NULL) ? handle->id : 0;
return (LIBUSB_SUCCESS);
}