From ced455398619b480e511d93f6c9664ae99978557 Mon Sep 17 00:00:00 2001 From: Nathan Hjelm Date: Thu, 8 Jul 2021 22:43:28 -0600 Subject: [PATCH] darwin: fix SEGV on libusb_close after failed re-enumeration This commit fixes an issue that can occur if the user calls libusb_close after a failed attempt of libusb_reset (re-enumerate). This can lead to an attempt to dereference dpriv->device which was set to NULL during the re-enumeration. Signed-off-by: Nathan Hjelm --- libusb/os/darwin_usb.c | 10 ++++++++-- libusb/version_nano.h | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c index bad0d8e..5faf18a 100644 --- a/libusb/os/darwin_usb.c +++ b/libusb/os/darwin_usb.c @@ -364,7 +364,7 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) { struct darwin_cached_device *old_device; io_service_t device; - UInt64 session; + UInt64 session, locationID; int ret; usbi_mutex_lock(&active_contexts_lock); @@ -374,6 +374,7 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) { /* get the location from the i/o registry */ ret = get_ioregistry_value_number (device, CFSTR("sessionID"), kCFNumberSInt64Type, &session); + (void) get_ioregistry_value_number (device, CFSTR("locationID"), kCFNumberSInt32Type, &locationID); IOObjectRelease (device); if (!ret) continue; @@ -386,7 +387,8 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) { if (old_device->in_reenumerate) { /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device() * will deref if needed. */ - usbi_dbg ("detected device detached due to re-enumeration"); + usbi_dbg ("detected device detached due to re-enumeration. sessionID: 0x%" PRIx64 ", locationID: 0x%" PRIx64, + session, locationID); /* the device object is no longer usable so go ahead and release it */ if (old_device->device) { @@ -1264,6 +1266,10 @@ static void darwin_close (struct libusb_device_handle *dev_handle) { } dpriv->open_count--; + if (NULL == dpriv->device) { + usbi_warn (HANDLE_CTX (dev_handle), "darwin_close device missing IOService"); + return; + } /* make sure all interfaces are released */ for (i = 0 ; i < USB_MAXINTERFACES ; i++) diff --git a/libusb/version_nano.h b/libusb/version_nano.h index d91ea7a..9064596 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11634 +#define LIBUSB_NANO 11635 -- 2.7.4