git: 6bda9f26d2ed - main - libusb: change callback register handler to int

Ed Maste <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a886730.35f51.2e326a31__33206.0917442263$1787324250$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by emaste:

URL: https://cgit.FreeBSD.org/src/commit/?id=6bda9f26d2eda066285a55edd0e508b799b1a02a

commit 6bda9f26d2eda066285a55edd0e508b799b1a02a
Author:     ShengYi Hung <[email protected]>
AuthorDate: 2025-12-13 15:12:11 +0000
Commit:     Ed Maste <[email protected]>
CommitDate: 2026-08-21 14:52:56 +0000

    libusb: change callback register handler to int
    
    libusb upstream uses int for register handler. This causes some library
    user (like pyusb) to assume that we have int in all implementations and
    therefore provides a 4 byte storage only. This causes Segmentation
    fault as we will right the pointer.
    
    Reviewed by:    adrian
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D54211
    
    (cherry picked from commit ce9ced951a0b9d004a3b007d4ac6e9087a1301a2)
---
 lib/libusb/libusb.h           |  5 ++---
 lib/libusb/libusb10.c         |  1 +
 lib/libusb/libusb10.h         |  2 ++
 lib/libusb/libusb10_hotplug.c | 50 +++++++++++++++++++++++++++----------------
 4 files changed, 37 insertions(+), 21 deletions(-)

diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h
index c432bb9f7793..70d0a516f50d 100644
--- a/lib/libusb/libusb.h
+++ b/lib/libusb/libusb.h
@@ -308,7 +308,6 @@ struct libusb_context;
 struct libusb_device;
 struct libusb_transfer;
 struct libusb_device_handle;
-struct libusb_hotplug_callback_handle_struct;
 
 struct libusb_pollfd {
 	int	fd;
@@ -341,7 +340,7 @@ typedef struct libusb_device_handle libusb_device_handle;
 typedef struct libusb_pollfd libusb_pollfd;
 typedef void (*libusb_pollfd_added_cb) (int fd, short events, void *user_data);
 typedef void (*libusb_pollfd_removed_cb) (int fd, void *user_data);
-typedef struct libusb_hotplug_callback_handle_struct *libusb_hotplug_callback_handle;
+typedef int libusb_hotplug_callback_handle;
 
 typedef struct libusb_device_descriptor {
 	uint8_t	bLength;
@@ -672,7 +671,7 @@ typedef int (*libusb_hotplug_callback_fn)(libusb_context *ctx,
     libusb_device *device, libusb_hotplug_event event, void *user_data);
 
 int	libusb_hotplug_register_callback(libusb_context *ctx, libusb_hotplug_event events, libusb_hotplug_flag flags, int vendor_id, int product_id, int dev_class, libusb_hotplug_callback_fn cb_fn, void *user_data, libusb_hotplug_callback_handle *handle);
-void	libusb_hotplug_deregister_callback(libusb_context *ctx, libusb_hotplug_callback_handle handle);
+void	libusb_hotplug_deregister_callback(libusb_context *ctx, libusb_hotplug_callback_handle callback_handle);
 void   *libusb_hotplug_get_user_data(struct libusb_context *ctx,
     libusb_hotplug_callback_handle callback_handle);
 
diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c
index f1afc5e135e7..516303e9cd0c 100644
--- a/lib/libusb/libusb10.c
+++ b/lib/libusb/libusb10.c
@@ -206,6 +206,7 @@ libusb_init_context(libusb_context **context,
 
 	memset(ctx, 0, sizeof(*ctx));
 	ctx->devd_pipe = -1;
+	ctx->next_callback_id = 1;
 
 	debug = getenv("LIBUSB_DEBUG");
 	ctx->log_cb = NULL;
diff --git a/lib/libusb/libusb10.h b/lib/libusb/libusb10.h
index 1036270da00b..714df3e4baf6 100644
--- a/lib/libusb/libusb10.h
+++ b/lib/libusb/libusb10.h
@@ -80,6 +80,7 @@ struct libusb_hotplug_callback_handle_struct {
 	int devclass;
 	libusb_hotplug_callback_fn fn;
 	void *user_data;
+	int id;
 };
 
 TAILQ_HEAD(libusb_device_head, libusb_device);
@@ -120,6 +121,7 @@ struct libusb_context {
 	void   *fd_cb_user_data;
 	libusb_log_cb log_cb;
 	int no_discovery;
+	int next_callback_id;
 
 	/* backend context holding the USB file descriptors */
 	struct libusb20_be_ctx *be_ctx;
diff --git a/lib/libusb/libusb10_hotplug.c b/lib/libusb/libusb10_hotplug.c
index 8b8de5019e4e..ee0fea82a8fe 100644
--- a/lib/libusb/libusb10_hotplug.c
+++ b/lib/libusb/libusb10_hotplug.c
@@ -176,8 +176,9 @@ libusb_hotplug_equal(libusb_device *_adev, libusb_device *_bdev)
 }
 
 static int
-libusb_hotplug_filter(libusb_context *ctx, libusb_hotplug_callback_handle pcbh,
-    libusb_device *dev, libusb_hotplug_event event)
+libusb_hotplug_filter(libusb_context *ctx,
+    struct libusb_hotplug_callback_handle_struct *pcbh, libusb_device *dev,
+    libusb_hotplug_event event)
 {
 	if (!(pcbh->events & event))
 		return (0);
@@ -216,8 +217,7 @@ libusb_hotplug_scan(void *arg)
 {
 	struct pollfd pfd;
 	struct libusb_device_head hotplug_devs;
-	libusb_hotplug_callback_handle acbh;
-	libusb_hotplug_callback_handle bcbh;
+	struct libusb_hotplug_callback_handle_struct *acbh, *bcbh;
 	libusb_context *ctx = arg;
 	libusb_device *temp;
 	libusb_device *adev;
@@ -343,7 +343,7 @@ int libusb_hotplug_register_callback(libusb_context *ctx,
     libusb_hotplug_callback_fn cb_fn, void *user_data,
     libusb_hotplug_callback_handle *phandle)
 {
-	libusb_hotplug_callback_handle handle;
+	struct libusb_hotplug_callback_handle_struct *handle;
 	struct libusb_device *adev;
 
 	ctx = GET_CONTEXT(ctx);
@@ -368,6 +368,17 @@ int libusb_hotplug_register_callback(libusb_context *ctx,
 	if (handle == NULL)
 		return (LIBUSB_ERROR_NO_MEM);
 
+	handle->events = events;
+	handle->vendor = vendor_id;
+	handle->product = product_id;
+	handle->devclass = dev_class;
+	handle->fn = cb_fn;
+	handle->user_data = user_data;
+	CTX_LOCK(ctx);
+	if ((handle->id = ctx->next_callback_id++) < 0)
+		handle->id = ctx->next_callback_id = 1;
+	CTX_UNLOCK(ctx);
+
 	HOTPLUG_LOCK(ctx);
 	if (ctx->hotplug_handler == NO_THREAD) {
 	  	libusb_hotplug_enumerate(ctx, &ctx->hotplug_devs);
@@ -376,12 +387,6 @@ int libusb_hotplug_register_callback(libusb_context *ctx,
 		    &libusb_hotplug_scan, ctx) != 0)
 			ctx->hotplug_handler = NO_THREAD;
 	}
-	handle->events = events;
-	handle->vendor = vendor_id;
-	handle->product = product_id;
-	handle->devclass = dev_class;
-	handle->fn = cb_fn;
-	handle->user_data = user_data;
 
 	if (flags & LIBUSB_HOTPLUG_ENUMERATE) {
 		TAILQ_FOREACH(adev, &ctx->hotplug_devs, hotplug_entry) {
@@ -398,23 +403,32 @@ int libusb_hotplug_register_callback(libusb_context *ctx,
 	HOTPLUG_UNLOCK(ctx);
 
 	if (phandle != NULL)
-		*phandle = handle;
+		*phandle = handle->id;
 	return (LIBUSB_SUCCESS);
 }
 
 void libusb_hotplug_deregister_callback(libusb_context *ctx,
-    libusb_hotplug_callback_handle handle)
+    libusb_hotplug_callback_handle callback_handle)
 {
-  	ctx = GET_CONTEXT(ctx);
+	struct libusb_hotplug_callback_handle_struct *handle;
 
-	if (ctx == NULL || handle == NULL)
+	ctx = GET_CONTEXT(ctx);
+
+	if (ctx == NULL || callback_handle == 0)
 		return;
 
 	HOTPLUG_LOCK(ctx);
+	TAILQ_FOREACH(handle, &ctx->hotplug_cbh, entry) {
+		if (handle->id == callback_handle)
+			break;
+	}
+	if (handle == NULL)
+		goto clean;
 	TAILQ_REMOVE(&ctx->hotplug_cbh, handle, entry);
 	libusb_interrupt_event_handler(ctx);
-	HOTPLUG_UNLOCK(ctx);
 
+clean:
+	HOTPLUG_UNLOCK(ctx);
 	free(handle);
 }
 
@@ -422,13 +436,13 @@ void *
 libusb_hotplug_get_user_data(struct libusb_context *ctx,
     libusb_hotplug_callback_handle callback_handle)
 {
-	libusb_hotplug_callback_handle handle;
+	struct libusb_hotplug_callback_handle_struct *handle;
 
 	ctx = GET_CONTEXT(ctx);
 
 	HOTPLUG_LOCK(ctx);
 	TAILQ_FOREACH(handle, &ctx->hotplug_cbh, entry) {
-		if (handle == callback_handle)
+		if (handle->id == callback_handle)
 			break;
 	}
 	HOTPLUG_UNLOCK(ctx);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.