Skip to content

Commit 4bacaa9

Browse files
committed
libusb: fix a few more crashes
1 parent 688dcad commit 4bacaa9

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

patches/libusb-1.0.25.patch

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,3 +947,98 @@ index cde286e7..22f151c1 100644
947947
--
948948
2.41.0
949949

950+
From 80a7d8ed3d6f3b6750432c1c87a74b2b1db03685 Mon Sep 17 00:00:00 2001
951+
From: osy <[email protected]>
952+
Date: Wed, 1 Oct 2025 12:00:09 -0700
953+
Subject: [PATCH 1/2] darwin: handle error from GetConfigurationDescriptorPtr
954+
955+
When a device is disconnected or otherwise `dpriv->device` is invalid,
956+
`GetConfigurationDescriptorPtr` will return `kIOReturnNoDevice` and
957+
`IOUSBConfigurationDescriptorPtr` will not be set. This means that we
958+
have an uninitialized pointer that is read from which is... very bad.
959+
---
960+
libusb/os/darwin_usb.c | 14 +++++++++-----
961+
1 file changed, 9 insertions(+), 5 deletions(-)
962+
963+
diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c
964+
index 58414a31..d385a0e8 100644
965+
--- a/libusb/os/darwin_usb.c
966+
+++ b/libusb/os/darwin_usb.c
967+
@@ -698,9 +698,9 @@ static int get_configuration_index (struct libusb_device *dev, UInt8 config_valu
968+
return darwin_to_libusb (kresult);
969+
970+
for (i = 0 ; i < numConfig ; i++) {
971+
- (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
972+
+ kresult = (*(priv->device))->GetConfigurationDescriptorPtr (priv->device, i, &desc);
973+
974+
- if (desc->bConfigurationValue == config_value)
975+
+ if (kresult == kIOReturnSuccess && desc->bConfigurationValue == config_value)
976+
return i;
977+
}
978+
979+
@@ -1823,7 +1823,11 @@ static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, b
980+
cached_configurations = alloca (sizeof (*cached_configurations) * descriptor.bNumConfigurations);
981+
982+
for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
983+
- (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
984+
+ kresult = (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
985+
+ if (kresult != kIOReturnSuccess) {
986+
+ dpriv->in_reenumerate = false;
987+
+ return LIBUSB_ERROR_NOT_FOUND;
988+
+ }
989+
memcpy (cached_configurations + i, cached_configuration, sizeof (cached_configurations[i]));
990+
}
991+
992+
@@ -1883,8 +1887,8 @@ static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, b
993+
}
994+
995+
for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
996+
- (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
997+
- if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
998+
+ kresult = (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
999+
+ if (kresult != kIOReturnSuccess || memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
1000+
usbi_dbg (ctx, "darwin/reenumerate_device: configuration descriptor %d changed", i);
1001+
return LIBUSB_ERROR_NOT_FOUND;
1002+
}
1003+
--
1004+
2.41.0
1005+
1006+
From 9eaebb714169264c346bcba0100ac650aba40002 Mon Sep 17 00:00:00 2001
1007+
From: osy <[email protected]>
1008+
Date: Wed, 1 Oct 2025 12:17:02 -0700
1009+
Subject: [PATCH 2/2] darwin: do not set NULL device in darwin_reload_device
1010+
1011+
We need to maintain the invariant that `device` is never an invalid
1012+
pointer because another thread might be concurrently accessing it. We
1013+
want that thread to error from an outdated `device` rather than crash
1014+
on a NULL pointer.
1015+
---
1016+
libusb/os/darwin_usb.c | 8 +++++---
1017+
1 file changed, 5 insertions(+), 3 deletions(-)
1018+
1019+
diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c
1020+
index d385a0e8..6407d7b6 100644
1021+
--- a/libusb/os/darwin_usb.c
1022+
+++ b/libusb/os/darwin_usb.c
1023+
@@ -2540,13 +2540,15 @@ static bool darwin_has_capture_entitlements (void) {
1024+
static int darwin_reload_device (struct libusb_device_handle *dev_handle) {
1025+
struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
1026+
enum libusb_error err;
1027+
+ usb_device_t **new_device;
1028+
1029+
usbi_mutex_lock(&darwin_cached_devices_mutex);
1030+
- (*(dpriv->device))->Release(dpriv->device);
1031+
- dpriv->device = darwin_device_from_service (HANDLE_CTX (dev_handle), dpriv->service);
1032+
- if (!dpriv->device) {
1033+
+ new_device = darwin_device_from_service (HANDLE_CTX (dev_handle), dpriv->service);
1034+
+ if (!new_device) {
1035+
err = LIBUSB_ERROR_NO_DEVICE;
1036+
} else {
1037+
+ (*(dpriv->device))->Release(dpriv->device);
1038+
+ dpriv->device = new_device;
1039+
err = LIBUSB_SUCCESS;
1040+
}
1041+
usbi_mutex_unlock(&darwin_cached_devices_mutex);
1042+
--
1043+
2.41.0
1044+

0 commit comments

Comments
 (0)