Update to 1.0.26
This commit is contained in:
parent
b6b18ebcd9
commit
91d4c17a0b
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
/libusb-1.0.24.tar.bz2
|
/libusb-1.0.24.tar.bz2
|
||||||
/libusb-1.0.25.tar.bz2
|
/libusb-1.0.25.tar.bz2
|
||||||
|
/libusb-1.0.26.tar.bz2
|
||||||
|
@ -1,158 +0,0 @@
|
|||||||
From d46cbbac4851ce6e49d8dacb0daa328453eb8a84 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Benjamin Berg <bberg@redhat.com>
|
|
||||||
Date: Tue, 22 Feb 2022 11:45:38 +0100
|
|
||||||
Subject: [PATCH] core: Install first context as implicit default
|
|
||||||
|
|
||||||
There was a behaviour change in libusb, which triggers issues when the
|
|
||||||
API is misused. This caused gutenprint to crash, see
|
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=2055504
|
|
||||||
|
|
||||||
For now, work around this by installing an implicit default. But, change
|
|
||||||
the code to log an error in case this "feature" is being used.
|
|
||||||
---
|
|
||||||
libusb/core.c | 16 +++++++++++++---
|
|
||||||
libusb/libusbi.h | 15 ++++++++++++++-
|
|
||||||
tests/umockdev.c | 31 +++++++++++++++++++++++++++++++
|
|
||||||
3 files changed, 58 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libusb/core.c b/libusb/core.c
|
|
||||||
index 1c1ada1..c75ddae 100644
|
|
||||||
--- a/libusb/core.c
|
|
||||||
+++ b/libusb/core.c
|
|
||||||
@@ -41,6 +41,7 @@ static libusb_log_cb log_handler;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct libusb_context *usbi_default_context;
|
|
||||||
+struct libusb_context *usbi_fallback_context;
|
|
||||||
static int default_context_refcnt;
|
|
||||||
static usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER;
|
|
||||||
static struct usbi_option default_context_options[LIBUSB_OPTION_MAX];
|
|
||||||
@@ -2284,7 +2285,7 @@ int API_EXPORTED libusb_init(libusb_context **ctx)
|
|
||||||
|
|
||||||
usbi_mutex_static_lock(&default_context_lock);
|
|
||||||
|
|
||||||
- if (!ctx && usbi_default_context) {
|
|
||||||
+ if (!ctx && default_context_refcnt > 0) {
|
|
||||||
usbi_dbg(usbi_default_context, "reusing default context");
|
|
||||||
default_context_refcnt++;
|
|
||||||
usbi_mutex_static_unlock(&default_context_lock);
|
|
||||||
@@ -2354,9 +2355,15 @@ int API_EXPORTED libusb_init(libusb_context **ctx)
|
|
||||||
goto err_io_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (ctx)
|
|
||||||
+ if (ctx) {
|
|
||||||
*ctx = _ctx;
|
|
||||||
|
|
||||||
+ if (!usbi_fallback_context) {
|
|
||||||
+ usbi_fallback_context = _ctx;
|
|
||||||
+ usbi_warn(usbi_fallback_context, "installing new context as implicit default");
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
usbi_mutex_static_unlock(&default_context_lock);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
@@ -2429,6 +2436,8 @@ void API_EXPORTED libusb_exit(libusb_context *ctx)
|
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
usbi_default_context = NULL;
|
|
||||||
+ if (ctx == usbi_fallback_context)
|
|
||||||
+ usbi_fallback_context = NULL;
|
|
||||||
|
|
||||||
usbi_mutex_static_unlock(&default_context_lock);
|
|
||||||
|
|
||||||
@@ -2575,7 +2584,8 @@ static void log_v(struct libusb_context *ctx, enum libusb_log_level level,
|
|
||||||
#else
|
|
||||||
enum libusb_log_level ctx_level;
|
|
||||||
|
|
||||||
- ctx = usbi_get_context(ctx);
|
|
||||||
+ ctx = ctx ? ctx : usbi_default_context;
|
|
||||||
+ ctx = ctx ? ctx : usbi_fallback_context;
|
|
||||||
if (ctx)
|
|
||||||
ctx_level = ctx->debug;
|
|
||||||
else
|
|
||||||
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
|
|
||||||
index 5f0d5c2..580add8 100644
|
|
||||||
--- a/libusb/libusbi.h
|
|
||||||
+++ b/libusb/libusbi.h
|
|
||||||
@@ -436,13 +436,26 @@ struct libusb_context {
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct libusb_context *usbi_default_context;
|
|
||||||
+extern struct libusb_context *usbi_fallback_context;
|
|
||||||
|
|
||||||
extern struct list_head active_contexts_list;
|
|
||||||
extern usbi_mutex_static_t active_contexts_lock;
|
|
||||||
|
|
||||||
static inline struct libusb_context *usbi_get_context(struct libusb_context *ctx)
|
|
||||||
{
|
|
||||||
- return ctx ? ctx : usbi_default_context;
|
|
||||||
+ static int warned = 0;
|
|
||||||
+
|
|
||||||
+ if (!ctx) {
|
|
||||||
+ ctx = usbi_default_context;
|
|
||||||
+ }
|
|
||||||
+ if (!ctx) {
|
|
||||||
+ ctx = usbi_fallback_context;
|
|
||||||
+ if (ctx && warned == 0) {
|
|
||||||
+ usbi_err(ctx, "API misuse! Using non-default context as implicit default.");
|
|
||||||
+ warned = 1;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum usbi_event_flags {
|
|
||||||
diff --git a/tests/umockdev.c b/tests/umockdev.c
|
|
||||||
index b2af512..0e73f94 100644
|
|
||||||
--- a/tests/umockdev.c
|
|
||||||
+++ b/tests/umockdev.c
|
|
||||||
@@ -551,6 +551,32 @@ test_open_close(UMockdevTestbedFixture * fixture, UNUSED_DATA)
|
|
||||||
libusb_close(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void
|
|
||||||
+test_implicit_default(UMockdevTestbedFixture * fixture, UNUSED_DATA)
|
|
||||||
+{
|
|
||||||
+ libusb_device **devs = NULL;
|
|
||||||
+
|
|
||||||
+ clear_libusb_log(fixture, LIBUSB_LOG_LEVEL_INFO);
|
|
||||||
+ g_assert_cmpint(libusb_get_device_list(NULL, &devs), ==, 1);
|
|
||||||
+ libusb_free_device_list(devs, TRUE);
|
|
||||||
+ assert_libusb_log_msg(fixture, LIBUSB_LOG_LEVEL_ERROR, "\\[usbi_get_context\\].*implicit default");
|
|
||||||
+
|
|
||||||
+ /* Only warns once */
|
|
||||||
+ g_assert_cmpint(libusb_get_device_list(NULL, &devs), ==, 1);
|
|
||||||
+ libusb_free_device_list(devs, TRUE);
|
|
||||||
+ clear_libusb_log(fixture, LIBUSB_LOG_LEVEL_INFO);
|
|
||||||
+
|
|
||||||
+ libusb_init(NULL);
|
|
||||||
+ g_assert_cmpint(libusb_get_device_list(NULL, &devs), ==, 1);
|
|
||||||
+ libusb_exit(NULL);
|
|
||||||
+
|
|
||||||
+ /* We free late, causing a warning from libusb_exit. However,
|
|
||||||
+ * we never see this warning (i.e. test success) because it is on a
|
|
||||||
+ * different context.
|
|
||||||
+ */
|
|
||||||
+ libusb_free_device_list(devs, TRUE);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void
|
|
||||||
test_close_flying(UMockdevTestbedFixture * fixture, UNUSED_DATA)
|
|
||||||
{
|
|
||||||
@@ -932,6 +958,11 @@ main(int argc, char **argv)
|
|
||||||
test_open_close,
|
|
||||||
test_fixture_teardown);
|
|
||||||
|
|
||||||
+ g_test_add("/libusb/implicit-default", UMockdevTestbedFixture, NULL,
|
|
||||||
+ test_fixture_setup_with_canon,
|
|
||||||
+ test_implicit_default,
|
|
||||||
+ test_fixture_teardown);
|
|
||||||
+
|
|
||||||
g_test_add("/libusb/close-flying", UMockdevTestbedFixture, NULL,
|
|
||||||
test_fixture_setup_with_canon,
|
|
||||||
test_close_flying,
|
|
||||||
--
|
|
||||||
2.35.1
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
24
1058.patch
24
1058.patch
@ -1,24 +0,0 @@
|
|||||||
From 2529a3fc4f987f93e0774af865ac7cb6557bd0c2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Benjamin Berg <bberg@redhat.com>
|
|
||||||
Date: Fri, 4 Feb 2022 22:50:28 +0100
|
|
||||||
Subject: [PATCH] core: Unset device ctx if it has been destroyed
|
|
||||||
|
|
||||||
Devices can outlive their context in some cases (in particular with
|
|
||||||
python garbage collection). Guard against this happening by clearing the
|
|
||||||
ctx pointer so that it is not pointing to uninitialized memory.
|
|
||||||
---
|
|
||||||
libusb/core.c | 1 +
|
|
||||||
1 file changed, 1 insertion(+)
|
|
||||||
|
|
||||||
diff --git a/libusb/core.c b/libusb/core.c
|
|
||||||
index 7893ac23..1c1ada14 100644
|
|
||||||
--- a/libusb/core.c
|
|
||||||
+++ b/libusb/core.c
|
|
||||||
@@ -2441,6 +2441,7 @@ void API_EXPORTED libusb_exit(libusb_context *ctx)
|
|
||||||
for_each_device(_ctx, dev) {
|
|
||||||
usbi_warn(_ctx, "device %d.%d still referenced",
|
|
||||||
dev->bus_number, dev->device_address);
|
|
||||||
+ DEVICE_CTX(dev) = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!list_empty(&_ctx->open_devs))
|
|
133
1073.patch
133
1073.patch
@ -1,133 +0,0 @@
|
|||||||
From 1cb11c5ba0d1d1266fe4ddd70f29d081f9d16802 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Benjamin Berg <bberg@redhat.com>
|
|
||||||
Date: Tue, 15 Feb 2022 11:13:41 +0100
|
|
||||||
Subject: [PATCH] io: Track device in usbi_transfer
|
|
||||||
|
|
||||||
transfer->dev_handle currently has the behaviour that it will be unset
|
|
||||||
if the device is closed. The sync API uses this fact to catch an error
|
|
||||||
case.
|
|
||||||
|
|
||||||
In other cases, transfer->dev_handle will keep its value, which means
|
|
||||||
that if the transfer lives longer than the device handle, the pointer
|
|
||||||
becomes invalid.
|
|
||||||
|
|
||||||
The transfer does however keep a reference to the device, which owns the
|
|
||||||
pointer to the context. As such, we can track this reference internal to
|
|
||||||
the transfer, and it is set while the transfer is in-flight.
|
|
||||||
|
|
||||||
With this, switch the logging infrastructure to use itransfer->dev->ctx
|
|
||||||
while checking that itransfer->dev is non-NULL.
|
|
||||||
|
|
||||||
Note that this was a regression caused by 6cae9c6dbd74 ("core: update
|
|
||||||
usbi_dbg to take the context as an argument"), specifically when
|
|
||||||
resolving the context while freeing a transfer after closing a device.
|
|
||||||
|
|
||||||
Note that the transfer will now keep a reference to the device until it
|
|
||||||
is free'ed. This allows it to use the correct context for logging even
|
|
||||||
in libusb_free_transfer.
|
|
||||||
|
|
||||||
The alternative to all this would be to just explicitly pass NULL to the
|
|
||||||
log handler in libusb_free_transfer.
|
|
||||||
---
|
|
||||||
libusb/io.c | 20 ++++++++++++--------
|
|
||||||
libusb/libusbi.h | 10 +++++++---
|
|
||||||
2 files changed, 19 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libusb/io.c b/libusb/io.c
|
|
||||||
index 0d2ac9ea..b919e9d9 100644
|
|
||||||
--- a/libusb/io.c
|
|
||||||
+++ b/libusb/io.c
|
|
||||||
@@ -1344,6 +1344,8 @@ void API_EXPORTED libusb_free_transfer(struct libusb_transfer *transfer)
|
|
||||||
|
|
||||||
itransfer = LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
|
|
||||||
usbi_mutex_destroy(&itransfer->lock);
|
|
||||||
+ if (itransfer->dev)
|
|
||||||
+ libusb_unref_device(itransfer->dev);
|
|
||||||
|
|
||||||
priv_size = PTR_ALIGN(usbi_backend.transfer_priv_size);
|
|
||||||
ptr = (unsigned char *)itransfer - priv_size;
|
|
||||||
@@ -1489,9 +1491,15 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
|
|
||||||
{
|
|
||||||
struct usbi_transfer *itransfer =
|
|
||||||
LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
|
|
||||||
- struct libusb_context *ctx = TRANSFER_CTX(transfer);
|
|
||||||
+ struct libusb_context *ctx;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
+ assert(transfer->dev_handle);
|
|
||||||
+ if (itransfer->dev)
|
|
||||||
+ libusb_unref_device(itransfer->dev);
|
|
||||||
+ itransfer->dev = libusb_ref_device(transfer->dev_handle->dev);
|
|
||||||
+
|
|
||||||
+ ctx = HANDLE_CTX(transfer->dev_handle);
|
|
||||||
usbi_dbg(ctx, "transfer %p", transfer);
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -1551,8 +1559,6 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
|
|
||||||
r = usbi_backend.submit_transfer(itransfer);
|
|
||||||
if (r == LIBUSB_SUCCESS) {
|
|
||||||
itransfer->state_flags |= USBI_TRANSFER_IN_FLIGHT;
|
|
||||||
- /* keep a reference to this device */
|
|
||||||
- libusb_ref_device(transfer->dev_handle->dev);
|
|
||||||
}
|
|
||||||
usbi_mutex_unlock(&itransfer->lock);
|
|
||||||
|
|
||||||
@@ -1659,7 +1665,6 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
|
|
||||||
{
|
|
||||||
struct libusb_transfer *transfer =
|
|
||||||
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
|
||||||
- struct libusb_device_handle *dev_handle = transfer->dev_handle;
|
|
||||||
struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
|
|
||||||
uint8_t flags;
|
|
||||||
int r;
|
|
||||||
@@ -1693,7 +1698,6 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
|
|
||||||
* this point. */
|
|
||||||
if (flags & LIBUSB_TRANSFER_FREE_TRANSFER)
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
- libusb_unref_device(dev_handle->dev);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1727,10 +1731,10 @@ int usbi_handle_transfer_cancellation(struct usbi_transfer *itransfer)
|
|
||||||
* function will be called the next time an event handler runs. */
|
|
||||||
void usbi_signal_transfer_completion(struct usbi_transfer *itransfer)
|
|
||||||
{
|
|
||||||
- libusb_device_handle *dev_handle = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer)->dev_handle;
|
|
||||||
+ struct libusb_device *dev = itransfer->dev;
|
|
||||||
|
|
||||||
- if (dev_handle) {
|
|
||||||
- struct libusb_context *ctx = HANDLE_CTX(dev_handle);
|
|
||||||
+ if (dev) {
|
|
||||||
+ struct libusb_context *ctx = DEVICE_CTX(dev);
|
|
||||||
unsigned int event_flags;
|
|
||||||
|
|
||||||
usbi_mutex_lock(&ctx->event_data_lock);
|
|
||||||
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
|
|
||||||
index 158a9af5..5f0d5c2e 100644
|
|
||||||
--- a/libusb/libusbi.h
|
|
||||||
+++ b/libusb/libusbi.h
|
|
||||||
@@ -329,10 +329,11 @@ void usbi_log(struct libusb_context *ctx, enum libusb_log_level level,
|
|
||||||
#endif /* ENABLE_LOGGING */
|
|
||||||
|
|
||||||
#define DEVICE_CTX(dev) ((dev)->ctx)
|
|
||||||
-#define HANDLE_CTX(handle) (DEVICE_CTX((handle)->dev))
|
|
||||||
-#define TRANSFER_CTX(transfer) (HANDLE_CTX((transfer)->dev_handle))
|
|
||||||
+#define HANDLE_CTX(handle) ((handle) ? DEVICE_CTX((handle)->dev) : NULL)
|
|
||||||
#define ITRANSFER_CTX(itransfer) \
|
|
||||||
- (TRANSFER_CTX(USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer)))
|
|
||||||
+ ((itransfer)->dev ? DEVICE_CTX((itransfer)->dev) : NULL)
|
|
||||||
+#define TRANSFER_CTX(transfer) \
|
|
||||||
+ (ITRANSFER_CTX(LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer)))
|
|
||||||
|
|
||||||
#define IS_EPIN(ep) (0 != ((ep) & LIBUSB_ENDPOINT_IN))
|
|
||||||
#define IS_EPOUT(ep) (!IS_EPIN(ep))
|
|
||||||
@@ -562,6 +563,9 @@ struct usbi_transfer {
|
|
||||||
uint32_t state_flags; /* Protected by usbi_transfer->lock */
|
|
||||||
uint32_t timeout_flags; /* Protected by the flying_stransfers_lock */
|
|
||||||
|
|
||||||
+ /* This is used for logging mostly. As long as it is set, the */
|
|
||||||
+ struct libusb_device *dev;
|
|
||||||
+
|
|
||||||
/* this lock is held during libusb_submit_transfer() and
|
|
||||||
* libusb_cancel_transfer() (allowing the OS backend to prevent duplicate
|
|
||||||
* cancellation, submission-during-cancellation, etc). the OS backend
|
|
@ -1,3 +1,6 @@
|
|||||||
|
* Fri Sep 30 2022 Kate Hsuan <hpa@redhat.com> 1.0.26-1
|
||||||
|
- Update to 1.0.26
|
||||||
|
|
||||||
* Wed Feb 02 2022 Benjamin Berg <bberg@redhat.com> 1.0.25-1
|
* Wed Feb 02 2022 Benjamin Berg <bberg@redhat.com> 1.0.25-1
|
||||||
- Update to 1.0.25
|
- Update to 1.0.25
|
||||||
|
|
||||||
|
14
libusb1.spec
14
libusb1.spec
@ -1,6 +1,6 @@
|
|||||||
Summary: Library for accessing USB devices
|
Summary: Library for accessing USB devices
|
||||||
Name: libusb1
|
Name: libusb1
|
||||||
Version: 1.0.25
|
Version: 1.0.26
|
||||||
Release: %autorelease
|
Release: %autorelease
|
||||||
Source0: https://github.com/libusb/libusb/releases/download/v%{version}/libusb-%{version}.tar.bz2
|
Source0: https://github.com/libusb/libusb/releases/download/v%{version}/libusb-%{version}.tar.bz2
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
@ -13,18 +13,6 @@ BuildRequires: gcc
|
|||||||
Provides: libusbx = %{version}-%{release}
|
Provides: libusbx = %{version}-%{release}
|
||||||
Obsoletes: libusbx < %{version}-%{release}
|
Obsoletes: libusbx < %{version}-%{release}
|
||||||
|
|
||||||
# Fix a crash after libusb_exit API has been misused
|
|
||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2050638
|
|
||||||
Patch0001: https://github.com/libusb/libusb/pull/1058.patch
|
|
||||||
# Fix a crash if a transfer outlives closing the device
|
|
||||||
Patch0002: https://github.com/libusb/libusb/pull/1073.patch
|
|
||||||
# Add umockdev based tests from https://github.com/libusb/libusb/pull/1078
|
|
||||||
Patch0003: 0001-tests-Add-some-umockdev-based-tests.patch
|
|
||||||
|
|
||||||
# Work around API misuse in gutenprint
|
|
||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2056326
|
|
||||||
Patch9999: 0001-core-Install-first-context-as-implicit-default.patch
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
This package provides a way for applications to access USB devices.
|
This package provides a way for applications to access USB devices.
|
||||||
|
|
||||||
|
2
sources
2
sources
@ -1 +1 @@
|
|||||||
SHA512 (libusb-1.0.25.tar.bz2) = f1e6e5577d4bd1ff136927dc66c615014a06ac332ddd797b1d1ad5f7b68e2405e66068dcb210e2f0ae3e31681603ef72efbd88bf7fbe0eb41ce700fdc3f92f9d
|
SHA512 (libusb-1.0.26.tar.bz2) = fcdb85c98f21639668693c2fd522814d440972d65883984c4ae53d0555bdbdb7e8c7a32199cd4b01113556a1eb5be7841b750cc73c9f6bda79bfe1af80914e71
|
||||||
|
Loading…
Reference in New Issue
Block a user