diff --git a/.gitignore b/.gitignore
index 810d34b..23bb556 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/libusb-1.0.24.tar.bz2
+SOURCES/libusb-1.0.25.tar.bz2
diff --git a/.libusbx.metadata b/.libusbx.metadata
index 4d9b532..85d3e2b 100644
--- a/.libusbx.metadata
+++ b/.libusbx.metadata
@@ -1 +1 @@
-d8d614b538f7c953b6e3b73f1eea5dc70820a7e2 SOURCES/libusb-1.0.24.tar.bz2
+490c33c303622af9b8bff521e6ed0818c64fa623 SOURCES/libusb-1.0.25.tar.bz2
diff --git a/SOURCES/0001-linux_usbfs-Accept-sysfs-attributes-not-terminated-w.patch b/SOURCES/0001-linux_usbfs-Accept-sysfs-attributes-not-terminated-w.patch
deleted file mode 100644
index 822fbe0..0000000
--- a/SOURCES/0001-linux_usbfs-Accept-sysfs-attributes-not-terminated-w.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From c486d01297a366aae8dcd3f715d0bfd8b995949b Mon Sep 17 00:00:00 2001
-From: Chris Dickens <christopher.a.dickens@gmail.com>
-Date: Mon, 8 Feb 2021 09:27:20 -0800
-Subject: [PATCH 1/2] linux_usbfs: Accept sysfs attributes not terminated with
- newline
-
-Benjamin Berg reports that some CI systems that simulate sysfs devices
-are causing libusb to report errors because such systems are not
-conforming to the sysfs pattern of terminating attribute values with a
-newline character. Reduce the severity of encountering such
-non-conforming attibute values from an error that prevents enumeration
-to a warning message.
-
-Closes #857
-
-Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
----
- libusb/os/linux_usbfs.c | 12 +++++++-----
- libusb/version_nano.h   |  2 +-
- 2 files changed, 8 insertions(+), 6 deletions(-)
-
-diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
-index 4882c0f..ebf8cfe 100644
---- a/libusb/os/linux_usbfs.c
-+++ b/libusb/os/linux_usbfs.c
-@@ -505,7 +505,7 @@ static int read_sysfs_attr(struct libusb_context *ctx,
- 	if (fd < 0)
- 		return fd;
- 
--	r = read(fd, buf, sizeof(buf));
-+	r = read(fd, buf, sizeof(buf) - 1);
- 	if (r < 0) {
- 		r = errno;
- 		close(fd);
-@@ -523,16 +523,18 @@ static int read_sysfs_attr(struct libusb_context *ctx,
- 		return 0;
- 	}
- 
--	/* The kernel does *not* NULL-terminate the string, but every attribute
-+	/* The kernel does *not* NUL-terminate the string, but every attribute
- 	 * should be terminated with a newline character. */
- 	if (!isdigit(buf[0])) {
- 		usbi_err(ctx, "attribute %s doesn't have numeric value?", attr);
- 		return LIBUSB_ERROR_IO;
- 	} else if (buf[r - 1] != '\n') {
--		usbi_err(ctx, "attribute %s doesn't end with newline?", attr);
--		return LIBUSB_ERROR_IO;
-+		usbi_warn(ctx, "attribute %s doesn't end with newline?", attr);
-+	} else {
-+		/* Remove the terminating newline character */
-+		r--;
- 	}
--	buf[r - 1] = '\0';
-+	buf[r] = '\0';
- 
- 	errno = 0;
- 	value = strtol(buf, &endptr, 10);
--- 
-2.29.2
-
diff --git a/SOURCES/0001-linux_usbfs-Fix-parsing-of-descriptors-for-multi-con.patch b/SOURCES/0001-linux_usbfs-Fix-parsing-of-descriptors-for-multi-con.patch
deleted file mode 100644
index 1908bf4..0000000
--- a/SOURCES/0001-linux_usbfs-Fix-parsing-of-descriptors-for-multi-con.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From f6d2cb561402c3b6d3627c0eb89e009b503d9067 Mon Sep 17 00:00:00 2001
-From: Chris Dickens <christopher.a.dickens@gmail.com>
-Date: Sun, 13 Dec 2020 15:49:19 -0800
-Subject: [PATCH] linux_usbfs: Fix parsing of descriptors for
- multi-configuration devices
-
-Commit e2be556bd2 ("linux_usbfs: Parse config descriptors during device
-initialization") introduced a regression for devices with multiple
-configurations. The logic that verifies the reported length of the
-configuration descriptors failed to count the length of the
-configuration descriptor itself and would truncate the actual length by
-9 bytes, leading to a parsing error for subsequent descriptors.
-
-Closes #825
-
-Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
----
- libusb/os/linux_usbfs.c | 12 ++++++++----
- libusb/version_nano.h   |  2 +-
- 2 files changed, 9 insertions(+), 5 deletions(-)
-
-diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
-index fb2ed53..4d2dc8d 100644
---- a/libusb/os/linux_usbfs.c
-+++ b/libusb/os/linux_usbfs.c
-@@ -641,7 +641,12 @@ static int seek_to_next_config(struct libusb_context *ctx,
- 	uint8_t *buffer, size_t len)
- {
- 	struct usbi_descriptor_header *header;
--	int offset = 0;
-+	int offset;
-+
-+	/* Start seeking past the config descriptor */
-+	offset = LIBUSB_DT_CONFIG_SIZE;
-+	buffer += LIBUSB_DT_CONFIG_SIZE;
-+	len -= LIBUSB_DT_CONFIG_SIZE;
- 
- 	while (len > 0) {
- 		if (len < 2) {
-@@ -718,7 +723,7 @@ static int parse_config_descriptors(struct libusb_device *dev)
- 		}
- 
- 		if (priv->sysfs_dir) {
--			 /*
-+			/*
- 			 * In sysfs wTotalLength is ignored, instead the kernel returns a
- 			 * config descriptor with verified bLength fields, with descriptors
- 			 * with an invalid bLength removed.
-@@ -727,8 +732,7 @@ static int parse_config_descriptors(struct libusb_device *dev)
- 			int offset;
- 
- 			if (num_configs > 1 && idx < num_configs - 1) {
--				offset = seek_to_next_config(ctx, buffer + LIBUSB_DT_CONFIG_SIZE,
--							     remaining - LIBUSB_DT_CONFIG_SIZE);
-+				offset = seek_to_next_config(ctx, buffer, remaining);
- 				if (offset < 0)
- 					return offset;
- 				sysfs_config_len = (uint16_t)offset;
--- 
-2.29.2
-
diff --git a/SOURCES/0002-linux_usbfs-Gracefully-handle-buggy-devices-with-a-c.patch b/SOURCES/0002-linux_usbfs-Gracefully-handle-buggy-devices-with-a-c.patch
deleted file mode 100644
index b95a501..0000000
--- a/SOURCES/0002-linux_usbfs-Gracefully-handle-buggy-devices-with-a-c.patch
+++ /dev/null
@@ -1,220 +0,0 @@
-From f38f09da98acc63966b65b72029b1f7f81166bef Mon Sep 17 00:00:00 2001
-From: Chris Dickens <christopher.a.dickens@gmail.com>
-Date: Mon, 8 Feb 2021 11:56:13 -0800
-Subject: [PATCH 2/2] linux_usbfs: Gracefully handle buggy devices with a
- configuration 0
-
-The USB spec states that a configuration value of 0 is reserved and is
-used to indicate the device in not configured (e.g. is in the address
-state). Unfortunately some devices do exist that violate this and use 0
-as the bConfigurationValue of the configuration descriptor.
-
-Improve how the Linux backend handles such non-conformant devices by
-adding special handling around the configuration value 0. Most devices
-will not require this special handling, but for those that do there is
-no way to distinguish between the device being unconfigured and using
-configuration 0.
-
-Closes #850
-
-Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
----
- libusb/os/linux_usbfs.c | 94 ++++++++++++++++++++++++++---------------
- libusb/version_nano.h   |  2 +-
- 2 files changed, 60 insertions(+), 36 deletions(-)
-
-diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
-index ebf8cfe..3a1894c 100644
---- a/libusb/os/linux_usbfs.c
-+++ b/libusb/os/linux_usbfs.c
-@@ -128,7 +128,7 @@ struct linux_device_priv {
- 	void *descriptors;
- 	size_t descriptors_len;
- 	struct config_descriptor *config_descriptors;
--	uint8_t active_config; /* cache val for !sysfs_available  */
-+	int active_config; /* cache val for !sysfs_available  */
- };
- 
- struct linux_device_handle_priv {
-@@ -169,6 +169,21 @@ struct linux_transfer_priv {
- 	int iso_packet_offset;
- };
- 
-+static int dev_has_config0(struct libusb_device *dev)
-+{
-+	struct linux_device_priv *priv = usbi_get_device_priv(dev);
-+	struct config_descriptor *config;
-+	uint8_t idx;
-+
-+	for (idx = 0; idx < dev->device_descriptor.bNumConfigurations; idx++) {
-+		config = &priv->config_descriptors[idx];
-+		if (config->desc->bConfigurationValue == 0)
-+			return 1;
-+	}
-+
-+	return 0;
-+}
-+
- static int get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
- {
- 	struct libusb_context *ctx = DEVICE_CTX(dev);
-@@ -574,22 +589,12 @@ static int sysfs_scan_device(struct libusb_context *ctx, const char *devname)
- }
- 
- /* read the bConfigurationValue for a device */
--static int sysfs_get_active_config(struct libusb_device *dev, uint8_t *config)
-+static int sysfs_get_active_config(struct libusb_device *dev, int *config)
- {
- 	struct linux_device_priv *priv = usbi_get_device_priv(dev);
--	int ret, tmp;
--
--	ret = read_sysfs_attr(DEVICE_CTX(dev), priv->sysfs_dir, "bConfigurationValue",
--			      UINT8_MAX, &tmp);
--	if (ret < 0)
--		return ret;
- 
--	if (tmp == -1)
--		tmp = 0;	/* unconfigured */
--
--	*config = (uint8_t)tmp;
--
--	return 0;
-+	return read_sysfs_attr(DEVICE_CTX(dev), priv->sysfs_dir, "bConfigurationValue",
-+			UINT8_MAX, config);
- }
- 
- int linux_get_device_address(struct libusb_context *ctx, int detached,
-@@ -765,6 +770,9 @@ static int parse_config_descriptors(struct libusb_device *dev)
- 			}
- 		}
- 
-+		if (config_desc->bConfigurationValue == 0)
-+			usbi_warn(ctx, "device has configuration 0");
-+
- 		priv->config_descriptors[idx].desc = config_desc;
- 		priv->config_descriptors[idx].actual_len = config_len;
- 
-@@ -798,7 +806,7 @@ static int op_get_active_config_descriptor(struct libusb_device *dev,
- {
- 	struct linux_device_priv *priv = usbi_get_device_priv(dev);
- 	void *config_desc;
--	uint8_t active_config;
-+	int active_config;
- 	int r;
- 
- 	if (priv->sysfs_dir) {
-@@ -810,12 +818,12 @@ static int op_get_active_config_descriptor(struct libusb_device *dev,
- 		active_config = priv->active_config;
- 	}
- 
--	if (active_config == 0) {
-+	if (active_config == -1) {
- 		usbi_err(DEVICE_CTX(dev), "device unconfigured");
- 		return LIBUSB_ERROR_NOT_FOUND;
- 	}
- 
--	r = op_get_config_descriptor_by_value(dev, active_config, &config_desc);
-+	r = op_get_config_descriptor_by_value(dev, (uint8_t)active_config, &config_desc);
- 	if (r < 0)
- 		return r;
- 
-@@ -863,17 +871,26 @@ static int usbfs_get_active_config(struct libusb_device *dev, int fd)
- 
- 		/* we hit this error path frequently with buggy devices :( */
- 		usbi_warn(DEVICE_CTX(dev), "get configuration failed, errno=%d", errno);
-+
-+		/* assume the current configuration is the first one if we have
-+		 * the configuration descriptors, otherwise treat the device
-+		 * as unconfigured. */
-+		if (priv->config_descriptors)
-+			priv->active_config = (int)priv->config_descriptors[0].desc->bConfigurationValue;
-+		else
-+			priv->active_config = -1;
- 	} else if (active_config == 0) {
--		/* some buggy devices have a configuration 0, but we're
--		 * reaching into the corner of a corner case here, so let's
--		 * not support buggy devices in these circumstances.
--		 * stick to the specs: a configuration value of 0 means
--		 * unconfigured. */
--		usbi_warn(DEVICE_CTX(dev), "active cfg 0? assuming unconfigured device");
-+		if (dev_has_config0(dev)) {
-+			/* some buggy devices have a configuration 0, but we're
-+			 * reaching into the corner of a corner case here. */
-+			priv->active_config = 0;
-+		} else {
-+			priv->active_config = -1;
-+		}
-+	} else {
-+		priv->active_config = (int)active_config;
- 	}
- 
--	priv->active_config = active_config;
--
- 	return LIBUSB_SUCCESS;
- }
- 
-@@ -1004,9 +1021,9 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
- 		usbi_warn(ctx, "Missing rw usbfs access; cannot determine "
- 			       "active configuration descriptor");
- 		if (priv->config_descriptors)
--			priv->active_config = priv->config_descriptors[0].desc->bConfigurationValue;
-+			priv->active_config = (int)priv->config_descriptors[0].desc->bConfigurationValue;
- 		else
--			priv->active_config = 0; /* No config dt */
-+			priv->active_config = -1; /* No config dt */
- 
- 		return LIBUSB_SUCCESS;
- 	}
-@@ -1428,22 +1445,27 @@ static int op_get_configuration(struct libusb_device_handle *handle,
- 	uint8_t *config)
- {
- 	struct linux_device_priv *priv = usbi_get_device_priv(handle->dev);
-+	int active_config;
- 	int r;
- 
- 	if (priv->sysfs_dir) {
--		r = sysfs_get_active_config(handle->dev, config);
-+		r = sysfs_get_active_config(handle->dev, &active_config);
- 	} else {
- 		struct linux_device_handle_priv *hpriv = usbi_get_device_handle_priv(handle);
- 
- 		r = usbfs_get_active_config(handle->dev, hpriv->fd);
- 		if (r == LIBUSB_SUCCESS)
--			*config = priv->active_config;
-+			active_config = priv->active_config;
- 	}
- 	if (r < 0)
- 		return r;
- 
--	if (*config == 0)
--		usbi_err(HANDLE_CTX(handle), "device unconfigured");
-+	if (active_config == -1) {
-+		usbi_warn(HANDLE_CTX(handle), "device unconfigured");
-+		active_config = 0;
-+	}
-+
-+	*config = (uint8_t)active_config;
- 
- 	return 0;
- }
-@@ -1467,11 +1489,13 @@ static int op_set_configuration(struct libusb_device_handle *handle, int config)
- 		return LIBUSB_ERROR_OTHER;
- 	}
- 
--	if (config == -1)
--		config = 0;
-+	/* if necessary, update our cached active config descriptor */
-+	if (!priv->sysfs_dir) {
-+		if (config == 0 && !dev_has_config0(handle->dev))
-+			config = -1;
- 
--	/* update our cached active config descriptor */
--	priv->active_config = (uint8_t)config;
-+		priv->active_config = config;
-+	}
- 
- 	return LIBUSB_SUCCESS;
- }
--- 
-2.29.2
-
diff --git a/SOURCES/1058.patch b/SOURCES/1058.patch
new file mode 100644
index 0000000..d504455
--- /dev/null
+++ b/SOURCES/1058.patch
@@ -0,0 +1,24 @@
+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))
diff --git a/SOURCES/1067.patch b/SOURCES/1067.patch
new file mode 100644
index 0000000..81a1333
--- /dev/null
+++ b/SOURCES/1067.patch
@@ -0,0 +1,786 @@
+From 8420de903a99fb6bfae22a21b2636858f2212baa Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Thu, 15 Jul 2021 17:07:09 +0200
+Subject: [PATCH 01/17] examples: Fix warning about uninitlised variable
+
+---
+ examples/fxload.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/examples/fxload.c b/examples/fxload.c
+index 541c3d3a3..85df69952 100644
+--- a/examples/fxload.c
++++ b/examples/fxload.c
+@@ -87,7 +87,8 @@ int main(int argc, char*argv[])
+ 	const char *type = NULL;
+ 	const char *fx_name[FX_TYPE_MAX] = FX_TYPE_NAMES;
+ 	const char *ext, *img_name[] = IMG_TYPE_NAMES;
+-	int fx_type = FX_TYPE_UNDEFINED, img_type[ARRAYSIZE(path)];
++	int fx_type = FX_TYPE_UNDEFINED;
++	int img_type[ARRAYSIZE(path)] = { IMG_TYPE_UNDEFINED, IMG_TYPE_UNDEFINED };
+ 	int opt, status;
+ 	unsigned int i, j;
+ 	unsigned vid = 0, pid = 0;
+
+From 23dcbd0521c56fb7543c4f8f73a2a1a4de69aa5e Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Thu, 15 Jul 2021 17:08:12 +0200
+Subject: [PATCH 02/17] core: Add non-null annotations to avoid static analyser
+ warnings
+
+It is only valid to call these inline functions with non-null values.
+However, static analysis may complain that the functions may dereference
+the pointer incorrectly if it is only looking at the function itself
+rather than including the surrounding code.
+
+Add the appropriate annotiations to both fix warnings and improve
+detection of bugs in API users.
+---
+ libusb/libusb.h  | 13 +++++++++++++
+ libusb/libusbi.h | 14 ++++++++++----
+ 2 files changed, 23 insertions(+), 4 deletions(-)
+
+diff --git a/libusb/libusb.h b/libusb/libusb.h
+index 61cacc95a..ea09fa8d9 100644
+--- a/libusb/libusb.h
++++ b/libusb/libusb.h
+@@ -77,8 +77,10 @@ typedef SSIZE_T ssize_t;
+ 
+ #if defined(__GNUC__)
+ #define LIBUSB_PACKED __attribute__ ((packed))
++#define LIBUSB_NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
+ #else
+ #define LIBUSB_PACKED
++#define LIBUSB_NONNULL(...)
+ #endif /* __GNUC__ */
+ 
+ /** \def LIBUSB_CALL
+@@ -1479,6 +1481,7 @@ int LIBUSB_CALL libusb_set_auto_detach_kernel_driver(
+  * \param transfer a transfer
+  * \returns pointer to the first byte of the data section
+  */
++LIBUSB_NONNULL(1)
+ static inline unsigned char *libusb_control_transfer_get_data(
+ 	struct libusb_transfer *transfer)
+ {
+@@ -1497,6 +1500,7 @@ static inline unsigned char *libusb_control_transfer_get_data(
+  * \param transfer a transfer
+  * \returns a casted pointer to the start of the transfer data buffer
+  */
++LIBUSB_NONNULL(1)
+ static inline struct libusb_control_setup *libusb_control_transfer_get_setup(
+ 	struct libusb_transfer *transfer)
+ {
+@@ -1526,6 +1530,7 @@ static inline struct libusb_control_setup *libusb_control_transfer_get_setup(
+  * \ref libusb_control_setup::wLength "wLength" field of
+  * \ref libusb_control_setup
+  */
++LIBUSB_NONNULL(1)
+ static inline void libusb_fill_control_setup(unsigned char *buffer,
+ 	uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
+ 	uint16_t wLength)
+@@ -1575,6 +1580,7 @@ uint32_t LIBUSB_CALL libusb_transfer_get_stream_id(
+  * \param user_data user data to pass to callback function
+  * \param timeout timeout for the transfer in milliseconds
+  */
++LIBUSB_NONNULL(1)
+ static inline void libusb_fill_control_transfer(
+ 	struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
+ 	unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data,
+@@ -1606,6 +1612,7 @@ static inline void libusb_fill_control_transfer(
+  * \param user_data user data to pass to callback function
+  * \param timeout timeout for the transfer in milliseconds
+  */
++LIBUSB_NONNULL(1)
+ static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer,
+ 	libusb_device_handle *dev_handle, unsigned char endpoint,
+ 	unsigned char *buffer, int length, libusb_transfer_cb_fn callback,
+@@ -1637,6 +1644,7 @@ static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer,
+  * \param user_data user data to pass to callback function
+  * \param timeout timeout for the transfer in milliseconds
+  */
++LIBUSB_NONNULL(1)
+ static inline void libusb_fill_bulk_stream_transfer(
+ 	struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
+ 	unsigned char endpoint, uint32_t stream_id,
+@@ -1662,6 +1670,7 @@ static inline void libusb_fill_bulk_stream_transfer(
+  * \param user_data user data to pass to callback function
+  * \param timeout timeout for the transfer in milliseconds
+  */
++LIBUSB_NONNULL(1)
+ static inline void libusb_fill_interrupt_transfer(
+ 	struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
+ 	unsigned char endpoint, unsigned char *buffer, int length,
+@@ -1691,6 +1700,7 @@ static inline void libusb_fill_interrupt_transfer(
+  * \param user_data user data to pass to callback function
+  * \param timeout timeout for the transfer in milliseconds
+  */
++LIBUSB_NONNULL(1)
+ static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer,
+ 	libusb_device_handle *dev_handle, unsigned char endpoint,
+ 	unsigned char *buffer, int length, int num_iso_packets,
+@@ -1715,6 +1725,7 @@ static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer,
+  * \param length the length to set in each isochronous packet descriptor
+  * \see libusb_get_max_packet_size()
+  */
++LIBUSB_NONNULL(1)
+ static inline void libusb_set_iso_packet_lengths(
+ 	struct libusb_transfer *transfer, unsigned int length)
+ {
+@@ -1740,6 +1751,7 @@ static inline void libusb_set_iso_packet_lengths(
+  * or NULL if the packet does not exist.
+  * \see libusb_get_iso_packet_buffer_simple()
+  */
++LIBUSB_NONNULL(1)
+ static inline unsigned char *libusb_get_iso_packet_buffer(
+ 	struct libusb_transfer *transfer, unsigned int packet)
+ {
+@@ -1782,6 +1794,7 @@ static inline unsigned char *libusb_get_iso_packet_buffer(
+  * or NULL if the packet does not exist.
+  * \see libusb_get_iso_packet_buffer()
+  */
++LIBUSB_NONNULL(1)
+ static inline unsigned char *libusb_get_iso_packet_buffer_simple(
+ 	struct libusb_transfer *transfer, unsigned int packet)
+ {
+diff --git a/libusb/libusbi.h b/libusb/libusbi.h
+index 158a9af58..6c924e548 100644
+--- a/libusb/libusbi.h
++++ b/libusb/libusbi.h
+@@ -192,11 +192,13 @@ struct list_head {
+ 
+ #define list_empty(entry) ((entry)->next == (entry))
+ 
++LIBUSB_NONNULL(1)
+ static inline void list_init(struct list_head *entry)
+ {
+ 	entry->prev = entry->next = entry;
+ }
+ 
++LIBUSB_NONNULL(1, 2)
+ static inline void list_add(struct list_head *entry, struct list_head *head)
+ {
+ 	entry->next = head->next;
+@@ -206,6 +208,7 @@ static inline void list_add(struct list_head *entry, struct list_head *head)
+ 	head->next = entry;
+ }
+ 
++LIBUSB_NONNULL(1, 2)
+ static inline void list_add_tail(struct list_head *entry,
+ 	struct list_head *head)
+ {
+@@ -216,6 +219,7 @@ static inline void list_add_tail(struct list_head *entry,
+ 	head->prev = entry;
+ }
+ 
++LIBUSB_NONNULL(1)
+ static inline void list_del(struct list_head *entry)
+ {
+ 	entry->next->prev = entry->prev;
+@@ -223,6 +227,7 @@ static inline void list_del(struct list_head *entry)
+ 	entry->next = entry->prev = NULL;
+ }
+ 
++LIBUSB_NONNULL(1, 2)
+ static inline void list_cut(struct list_head *list, struct list_head *head)
+ {
+ 	if (list_empty(head)) {
+@@ -755,10 +760,10 @@ struct usbi_hotplug_message {
+ 
+ /* shared data and functions */
+ 
+-void usbi_hotplug_init(struct libusb_context *ctx);
+-void usbi_hotplug_exit(struct libusb_context *ctx);
++void usbi_hotplug_init(struct libusb_context *ctx) LIBUSB_NONNULL(1);
++void usbi_hotplug_exit(struct libusb_context *ctx) LIBUSB_NONNULL(1);
+ void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev,
+-	libusb_hotplug_event event);
++	libusb_hotplug_event event) LIBUSB_NONNULL(1);
+ void usbi_hotplug_process(struct libusb_context *ctx, struct list_head *hotplug_msgs);
+ 
+ int usbi_io_init(struct libusb_context *ctx);
+@@ -789,7 +794,8 @@ struct usbi_event_source {
+ 
+ int usbi_add_event_source(struct libusb_context *ctx, usbi_os_handle_t os_handle,
+ 	short poll_events);
+-void usbi_remove_event_source(struct libusb_context *ctx, usbi_os_handle_t os_handle);
++void usbi_remove_event_source(struct libusb_context *ctx, usbi_os_handle_t os_handle)
++	LIBUSB_NONNULL(1);
+ 
+ struct usbi_option {
+   int is_set;
+
+From ac527ddcb72e6cd43f2e9d6ae973e9352856dcaf Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Wed, 9 Feb 2022 19:21:09 +0100
+Subject: [PATCH 03/17] core: Silence dereference warnings using assertions in
+ list_del
+
+It is guaranteed that entry->next and entry->prev are non-null for a
+list item that is part of a list. The static analyser might be confused
+though, so add an appropriate assert in case debug mode is enabled.
+---
+ libusb/libusbi.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/libusb/libusbi.h b/libusb/libusbi.h
+index 6c924e548..faf6b5daf 100644
+--- a/libusb/libusbi.h
++++ b/libusb/libusbi.h
+@@ -222,6 +222,10 @@ static inline void list_add_tail(struct list_head *entry,
+ LIBUSB_NONNULL(1)
+ static inline void list_del(struct list_head *entry)
+ {
++#ifndef NDEBUG
++	assert(entry->next && entry->prev);
++#endif
++
+ 	entry->next->prev = entry->prev;
+ 	entry->prev->next = entry->next;
+ 	entry->next = entry->prev = NULL;
+
+From f04d419c0e936333816c969605c2915d5592c328 Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Thu, 15 Jul 2021 17:11:41 +0200
+Subject: [PATCH 04/17] core: Fix incorrect free if reallocating to zero size
+
+A realloc to a size of 0 is equivalent to a free call. As such, in that
+case free'ing the original pointer would result in a double free. Fix
+this by adding a check that the new size if larger than zero.
+---
+ libusb/libusbi.h | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/libusb/libusbi.h b/libusb/libusbi.h
+index faf6b5daf..652d545ac 100644
+--- a/libusb/libusbi.h
++++ b/libusb/libusbi.h
+@@ -257,7 +257,14 @@ static inline void list_splice_front(struct list_head *list, struct list_head *h
+ 
+ static inline void *usbi_reallocf(void *ptr, size_t size)
+ {
+-	void *ret = realloc(ptr, size);
++	void *ret;
++
++	if (size == 0) {
++		free(ptr);
++		return NULL;
++	}
++
++	ret = realloc(ptr, size);
+ 
+ 	if (!ret)
+ 		free(ptr);
+
+From 883b04fe516adb93a6a1df6c2b4b26e9a4de32be Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Thu, 15 Jul 2021 17:13:18 +0200
+Subject: [PATCH 05/17] linux_usbfs: Work around static analyser thinking fd is
+ leaked
+
+Static analysis using coverity is detecting the file descriptor handle
+potentially being leaked in some situations. The code itself is actually
+sound, but coverity is not correctly following the fact that fd can be
+compared against wrapped_fd.
+
+Fix this by introducing an fd_close variable which is compared to a
+fixed value to decide whether to close the fd. Also switch to a goto
+pattern rather than returning from different places.
+---
+ libusb/os/linux_usbfs.c | 51 ++++++++++++++++++++++++-----------------
+ 1 file changed, 30 insertions(+), 21 deletions(-)
+
+diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
+index c3006753d..fe6319ee9 100644
+--- a/libusb/os/linux_usbfs.c
++++ b/libusb/os/linux_usbfs.c
+@@ -904,7 +904,8 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
+ 	struct linux_device_priv *priv = usbi_get_device_priv(dev);
+ 	struct libusb_context *ctx = DEVICE_CTX(dev);
+ 	size_t alloc_len;
+-	int fd, speed, r;
++	int fd, fd_close = -1;
++	int speed, r;
+ 	ssize_t nb;
+ 
+ 	dev->bus_number = busnum;
+@@ -934,19 +935,22 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
+ 
+ 	/* cache descriptors in memory */
+ 	if (sysfs_dir) {
+-		fd = open_sysfs_attr(ctx, sysfs_dir, "descriptors");
++		fd = fd_close = open_sysfs_attr(ctx, sysfs_dir, "descriptors");
+ 	} else if (wrapped_fd < 0) {
+-		fd = get_usbfs_fd(dev, O_RDONLY, 0);
++		fd = fd_close = get_usbfs_fd(dev, O_RDONLY, 0);
+ 	} else {
+ 		fd = wrapped_fd;
+ 		r = lseek(fd, 0, SEEK_SET);
+ 		if (r < 0) {
+ 			usbi_err(ctx, "lseek failed, errno=%d", errno);
+-			return LIBUSB_ERROR_IO;
++			r = LIBUSB_ERROR_IO;
++			goto out;
+ 		}
+ 	}
+-	if (fd < 0)
+-		return fd;
++	if (fd < 0) {
++		r = fd;
++		goto out;
++	}
+ 
+ 	alloc_len = 0;
+ 	do {
+@@ -956,9 +960,8 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
+ 		alloc_len += desc_read_length;
+ 		priv->descriptors = usbi_reallocf(priv->descriptors, alloc_len);
+ 		if (!priv->descriptors) {
+-			if (fd != wrapped_fd)
+-				close(fd);
+-			return LIBUSB_ERROR_NO_MEM;
++			r = LIBUSB_ERROR_NO_MEM;
++			goto out;
+ 		}
+ 		read_ptr = (uint8_t *)priv->descriptors + priv->descriptors_len;
+ 		/* usbfs has holes in the file */
+@@ -967,36 +970,39 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
+ 		nb = read(fd, read_ptr, desc_read_length);
+ 		if (nb < 0) {
+ 			usbi_err(ctx, "read descriptor failed, errno=%d", errno);
+-			if (fd != wrapped_fd)
+-				close(fd);
+-			return LIBUSB_ERROR_IO;
++			r = LIBUSB_ERROR_IO;
++			goto out;
+ 		}
+ 		priv->descriptors_len += (size_t)nb;
+ 	} while (priv->descriptors_len == alloc_len);
+ 
+-	if (fd != wrapped_fd)
+-		close(fd);
++	if (fd_close >= 0) {
++		close(fd_close);
++		fd_close = -1;
++	}
+ 
+ 	if (priv->descriptors_len < LIBUSB_DT_DEVICE_SIZE) {
+ 		usbi_err(ctx, "short descriptor read (%zu)", priv->descriptors_len);
+-		return LIBUSB_ERROR_IO;
++		r = LIBUSB_ERROR_IO;
++		goto out;
+ 	}
+ 
+ 	r = parse_config_descriptors(dev);
+ 	if (r < 0)
+-		return r;
++		goto out;
+ 
+ 	memcpy(&dev->device_descriptor, priv->descriptors, LIBUSB_DT_DEVICE_SIZE);
+ 
+ 	if (sysfs_dir) {
+ 		/* sysfs descriptors are in bus-endian format */
+ 		usbi_localize_device_descriptor(&dev->device_descriptor);
+-		return LIBUSB_SUCCESS;
++		r = LIBUSB_SUCCESS;
++		goto out;
+ 	}
+ 
+ 	/* cache active config */
+ 	if (wrapped_fd < 0)
+-		fd = get_usbfs_fd(dev, O_RDWR, 1);
++		fd = fd_close = get_usbfs_fd(dev, O_RDWR, 1);
+ 	else
+ 		fd = wrapped_fd;
+ 	if (fd < 0) {
+@@ -1009,12 +1015,15 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
+ 		else
+ 			priv->active_config = -1; /* No config dt */
+ 
+-		return LIBUSB_SUCCESS;
++		r = LIBUSB_SUCCESS;
++		goto out;
+ 	}
+ 
+ 	r = usbfs_get_active_config(dev, fd);
+-	if (fd != wrapped_fd)
+-		close(fd);
++
++out:
++	if (fd_close >= 0)
++		close(fd_close);
+ 
+ 	return r;
+ }
+
+From 06f4523117ffbe77fbc370a403cc274016867139 Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Wed, 9 Feb 2022 19:08:31 +0100
+Subject: [PATCH 06/17] examples: Fix warning about NULL pointer dereference
+
+It seems like coverity is getting confused by the transfers being global
+variables, thinking that img_transfer may become NULL again.
+
+Fix this bogus warning by moving the check down.
+---
+ examples/dpfp.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/examples/dpfp.c b/examples/dpfp.c
+index 682865053..4a871ee4f 100644
+--- a/examples/dpfp.c
++++ b/examples/dpfp.c
+@@ -554,13 +554,8 @@ static int do_init(void)
+ static int alloc_transfers(void)
+ {
+ 	img_transfer = libusb_alloc_transfer(0);
+-	if (!img_transfer) {
+-		errno = ENOMEM;
+-		return -1;
+-	}
+-
+ 	irq_transfer = libusb_alloc_transfer(0);
+-	if (!irq_transfer) {
++	if (!img_transfer || !irq_transfer) {
+ 		errno = ENOMEM;
+ 		return -1;
+ 	}
+
+From b2a2163b3893e57d839b5247072fcb2fdfd5d4e4 Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Wed, 9 Feb 2022 19:09:53 +0100
+Subject: [PATCH 07/17] examples: Assert the data fits into our static buffer
+
+---
+ examples/ezusb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/examples/ezusb.c b/examples/ezusb.c
+index 4bed12a4c..0ea787190 100644
+--- a/examples/ezusb.c
++++ b/examples/ezusb.c
+@@ -23,6 +23,7 @@
+ 
+ #include <config.h>
+ 
++#include <assert.h>
+ #include <stdio.h>
+ #include <errno.h>
+ #include <stdlib.h>
+@@ -303,6 +304,7 @@ static int parse_ihex(FILE *image, void *context,
+ 		buf[3] = 0;
+ 		len = strtoul(buf+1, NULL, 16);
+ 		buf[3] = tmp;
++		assert(len <= sizeof(data));
+ 
+ 		/* Read the target offset (address up to 64KB) */
+ 		tmp = buf[7];
+
+From 13fbb9923e4ee5b6d9dfa13396e1faf5da13a2af Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Wed, 9 Feb 2022 19:11:28 +0100
+Subject: [PATCH 08/17] core: Tell coverity that libusb_open does not free
+
+Internally, libusb_open does an unref in an error case. coverity doesn't
+seem to notice that this is balanced with the earlier ref, and thinks
+that the passed in device may be free'ed. Annotate the function to
+prevent misdetections.
+
+An alternative would be to only take the reference after checking for
+the error, but the code is idiomatic as-is.
+---
+ libusb/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libusb/core.c b/libusb/core.c
+index 7893ac238..076c2bbbd 100644
+--- a/libusb/core.c
++++ b/libusb/core.c
+@@ -1293,6 +1293,7 @@ int API_EXPORTED libusb_wrap_sys_device(libusb_context *ctx, intptr_t sys_dev,
+  * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+  * \returns another LIBUSB_ERROR code on other failure
+  */
++/* coverity[-free: arg-0] false positive due to error handling path */
+ int API_EXPORTED libusb_open(libusb_device *dev,
+ 	libusb_device_handle **dev_handle)
+ {
+
+From 1d576b41cfe229cbf98a3fc9aeb819562cccaaae Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Wed, 9 Feb 2022 19:13:26 +0100
+Subject: [PATCH 09/17] core: Remove unneeded bounds check
+
+This makes the code slightly less efficient, but shuts up warnings that
+the later switch ends up with dead error handling code.
+---
+ libusb/core.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/libusb/core.c b/libusb/core.c
+index 076c2bbbd..73fb6524a 100644
+--- a/libusb/core.c
++++ b/libusb/core.c
+@@ -2201,10 +2201,6 @@ int API_EXPORTED libusb_set_option(libusb_context *ctx,
+ 		return r;
+ 	}
+ 
+-	if (option >= LIBUSB_OPTION_MAX) {
+-		return LIBUSB_ERROR_INVALID_PARAM;
+-	}
+-
+ 	if (NULL == ctx) {
+ 		usbi_mutex_static_lock(&default_context_lock);
+ 		default_context_options[option].is_set = 1;
+
+From ca3e801e2f54308651a180e48e2381b5ed88eef1 Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Wed, 9 Feb 2022 19:15:16 +0100
+Subject: [PATCH 10/17] descriptor: Avoid uninitialized memory warnings
+
+The static analyzer has trouble understanding that get_config_descriptor
+fills in the config descriptor. Just initializing the memory silences
+the warning and is safe to do.
+---
+ libusb/descriptor.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libusb/descriptor.c b/libusb/descriptor.c
+index 253ef1c31..dbcf061d9 100644
+--- a/libusb/descriptor.c
++++ b/libusb/descriptor.c
+@@ -555,7 +555,7 @@ int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
+ int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev,
+ 	struct libusb_config_descriptor **config)
+ {
+-	union usbi_config_desc_buf _config;
++	union usbi_config_desc_buf _config = { 0, };
+ 	uint16_t config_len;
+ 	uint8_t *buf;
+ 	int r;
+@@ -658,7 +658,7 @@ int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
+ 
+ 	usbi_dbg(DEVICE_CTX(dev), "value %u", bConfigurationValue);
+ 	for (idx = 0; idx < dev->device_descriptor.bNumConfigurations; idx++) {
+-		union usbi_config_desc_buf _config;
++		union usbi_config_desc_buf _config = { 0, };
+ 
+ 		r = get_config_descriptor(dev, idx, _config.buf, sizeof(_config.buf));
+ 		if (r < 0)
+
+From e7a0c0d507d662ad3661f52286452880ef75f488 Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Wed, 9 Feb 2022 19:19:04 +0100
+Subject: [PATCH 11/17] io: Suppress invalid free warning from coverity
+
+Coverity is not understanding the pointer arithmetic involved with the
+transfer in-memory storage. As such, it flags the free as invalid, even
+though everything is fine. Add an appropriate comment to silence the
+warning.
+---
+ libusb/io.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/libusb/io.c b/libusb/io.c
+index 0d2ac9ea2..d32cdc1bf 100644
+--- a/libusb/io.c
++++ b/libusb/io.c
+@@ -1691,8 +1691,10 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
+ 		transfer->callback(transfer);
+ 	/* transfer might have been freed by the above call, do not use from
+ 	 * this point. */
+-	if (flags & LIBUSB_TRANSFER_FREE_TRANSFER)
++	if (flags & LIBUSB_TRANSFER_FREE_TRANSFER) {
++		/* coverity[incorrect_free] is reported incorrectly here due to the memory layout */
+ 		libusb_free_transfer(transfer);
++	}
+ 	libusb_unref_device(dev_handle->dev);
+ 	return r;
+ }
+
+From fc44484ef782bdb05880a26c502a7ea33c0eb72f Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Wed, 9 Feb 2022 19:20:27 +0100
+Subject: [PATCH 12/17] io: Suppress missing unlock warning from coverity
+
+The function is supposed to take the lock, as such, this is the expected
+behaviour.
+---
+ libusb/io.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libusb/io.c b/libusb/io.c
+index d32cdc1bf..96bd22861 100644
+--- a/libusb/io.c
++++ b/libusb/io.c
+@@ -1786,6 +1786,7 @@ int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
+ 		return 1;
+ 
+ 	ctx->event_handler_active = 1;
++	/* coverity[missing_unlock] is expected here */
+ 	return 0;
+ }
+ 
+
+From c97e4bb846f41a112262df668e9d8e449555f295 Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Wed, 9 Feb 2022 19:23:45 +0100
+Subject: [PATCH 13/17] events_posix: Silence warnings about zero-allocated
+ memory
+
+The static analyser got confused by the fact that fds may be NULL if
+there are no event sources. Obviously, in that case the later loop that
+dereferences fds will never do anything, but coverity seems to miss that
+part.
+
+Silence the warning by doing an early return from the function.
+---
+ libusb/os/events_posix.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/libusb/os/events_posix.c b/libusb/os/events_posix.c
+index 715a2d551..172f8afe8 100644
+--- a/libusb/os/events_posix.c
++++ b/libusb/os/events_posix.c
+@@ -201,6 +201,10 @@ int usbi_alloc_event_data(struct libusb_context *ctx)
+ 	for_each_event_source(ctx, ievent_source)
+ 		ctx->event_data_cnt++;
+ 
++	/* Silence warning about use of zero allocated memory. */
++	if (ctx->event_data_cnt == 0)
++		return 0;
++
+ 	fds = calloc(ctx->event_data_cnt, sizeof(*fds));
+ 	if (!fds)
+ 		return LIBUSB_ERROR_NO_MEM;
+
+From 7e9919314f82c61df6950390412ab3b80c84b707 Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Wed, 9 Feb 2022 19:25:40 +0100
+Subject: [PATCH 14/17] linux_usbfs: Disable sleep workaround when using udev
+
+The workaround to sleep 10ms if a device node has not yet been created
+is definitely not needed with udev. I am not sure what the race looks
+like in the netlink case, unless some other userspace daemon (udev) is
+reacting to the same message and creates the device.
+
+I suppose, in the long run this might be fixed by removing the netlink
+code.
+---
+ libusb/os/linux_usbfs.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
+index fe6319ee9..b4837895d 100644
+--- a/libusb/os/linux_usbfs.c
++++ b/libusb/os/linux_usbfs.c
+@@ -197,6 +197,8 @@ static int get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
+ 	if (fd != -1)
+ 		return fd; /* Success */
+ 
++/* This workaround is only relevant when watching netlink directly rather than udev. */
++#if !defined(HAVE_LIBUDEV)
+ 	if (errno == ENOENT) {
+ 		const long delay_ms = 10L;
+ 		const struct timespec delay_ts = { 0L, delay_ms * 1000L * 1000L };
+@@ -211,6 +213,7 @@ static int get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
+ 		if (fd != -1)
+ 			return fd; /* Success */
+ 	}
++#endif
+ 
+ 	if (!silent) {
+ 		usbi_err(ctx, "libusb couldn't open USB device %s, errno=%d", path, errno);
+
+From 126aacee12b49ed525534a81ad830db692654ba0 Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Wed, 9 Feb 2022 19:29:35 +0100
+Subject: [PATCH 15/17] linux_usbfs: Silence coverity warnings about returned
+ offset
+
+The seek_to_next_config function returns an offset. This was marked as
+tained by coverity, but really, we can trust it to be OK in the
+surrounding code. Mark the return value to silence the warnings.
+---
+ libusb/os/linux_usbfs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
+index b4837895d..ba55913f0 100644
+--- a/libusb/os/linux_usbfs.c
++++ b/libusb/os/linux_usbfs.c
+@@ -638,6 +638,7 @@ int linux_get_device_address(struct libusb_context *ctx, int detached,
+ }
+ 
+ /* Return offset of the next config descriptor */
++/* coverity[-taint_source] as the returned offset can be trusted */
+ static int seek_to_next_config(struct libusb_context *ctx,
+ 	uint8_t *buffer, size_t len)
+ {
+
+From 42679d2d8573dfc27b9c78f832749728997a516b Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Wed, 9 Feb 2022 19:31:44 +0100
+Subject: [PATCH 16/17] linux_usbfs: Silence coverity warning about missing
+ locking
+
+The reap_status field is locked in most cases when it is accessed.
+This causes a warning from coverity, however locking is not needed in
+this particular case as the transfer has not yet been submitted.
+
+As such, add an appropriate comment to silence the warning.
+---
+ libusb/os/linux_usbfs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
+index ba55913f0..2e65d66ce 100644
+--- a/libusb/os/linux_usbfs.c
++++ b/libusb/os/linux_usbfs.c
+@@ -1984,6 +1984,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
+ 	tpriv->num_urbs = num_urbs;
+ 	tpriv->num_retired = 0;
+ 	tpriv->reap_action = NORMAL;
++	/* coverity[missing_lock] as we don't need to lock before submission */
+ 	tpriv->reap_status = LIBUSB_TRANSFER_COMPLETED;
+ 
+ 	for (i = 0; i < num_urbs; i++) {
+
+From 38cff7a438f7a00d76aa03cc1c35f6be395c167d Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Thu, 10 Feb 2022 10:51:11 +0100
+Subject: [PATCH 17/17] core: Silence coverity by handling long log messages in
+ one statement
+
+Having two statements seems to confuse coverity. Having two checks right
+after each other doesn't give us anything, so just fold them into one so
+that the static analyzer is not getting confused.
+---
+ libusb/core.c | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+diff --git a/libusb/core.c b/libusb/core.c
+index 73fb6524a..03adcb758 100644
+--- a/libusb/core.c
++++ b/libusb/core.c
+@@ -2629,16 +2629,13 @@ static void log_v(struct libusb_context *ctx, enum libusb_log_level level,
+ 		header_len = 0;
+ 	}
+ 
+-	text_len = vsnprintf(buf + header_len, sizeof(buf) - (size_t)header_len,
++	text_len = vsnprintf(buf + header_len,
++		sizeof(buf) - (size_t)header_len - (int)sizeof(USBI_LOG_LINE_END),
+ 		format, args);
+-	if (text_len < 0 || text_len + header_len >= (int)sizeof(buf)) {
++	if (text_len < 0 || text_len + header_len + (int)sizeof(USBI_LOG_LINE_END) >= (int)sizeof(buf)) {
+ 		/* Truncated log output. On some platforms a -1 return value means
+-		 * that the output was truncated. */
+-		text_len = (int)sizeof(buf) - header_len;
+-	}
+-	if (header_len + text_len + (int)sizeof(USBI_LOG_LINE_END) >= (int)sizeof(buf)) {
+-		/* Need to truncate the text slightly to fit on the terminator. */
+-		text_len -= (header_len + text_len + (int)sizeof(USBI_LOG_LINE_END)) - (int)sizeof(buf);
++		 * that the output was truncated (e.g. glibc < 2.1). */
++		text_len = (int)sizeof(buf) - header_len - (int)sizeof(USBI_LOG_LINE_END);
+ 	}
+ 	strcpy(buf + header_len + text_len, USBI_LOG_LINE_END);
+ 
diff --git a/SOURCES/1073.patch b/SOURCES/1073.patch
new file mode 100644
index 0000000..8b91a48
--- /dev/null
+++ b/SOURCES/1073.patch
@@ -0,0 +1,72 @@
+From bf833ee6adf58bd4a4a468aa729cdc78bdc13ede Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Tue, 15 Feb 2022 11:13:41 +0100
+Subject: [PATCH 1/2] core: Catch NULL dev_handle when getting a transfer's
+ context
+
+The dev_handle will be set to NULL when the transfer is still in-flight
+while the device is closed. In that case, the transfer free function
+will try to access the context and would run into a NULL pointer
+dereference.
+
+Add a test for dev_handle being valid before dereferencing it further.
+---
+ libusb/libusbi.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libusb/libusbi.h b/libusb/libusbi.h
+index 158a9af5..dde43df2 100644
+--- a/libusb/libusbi.h
++++ b/libusb/libusbi.h
+@@ -330,7 +330,7 @@ void usbi_log(struct libusb_context *ctx, enum libusb_log_level level,
+ 
+ #define DEVICE_CTX(dev)		((dev)->ctx)
+ #define HANDLE_CTX(handle)	(DEVICE_CTX((handle)->dev))
+-#define TRANSFER_CTX(transfer)	(HANDLE_CTX((transfer)->dev_handle))
++#define TRANSFER_CTX(transfer)	((transfer)->dev_handle ? HANDLE_CTX((transfer)->dev_handle) : NULL)
+ #define ITRANSFER_CTX(itransfer) \
+ 	(TRANSFER_CTX(USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer)))
+ 
+
+From 6428090ea77dfb80906a146977ea7fd6de4718c8 Mon Sep 17 00:00:00 2001
+From: Benjamin Berg <bberg@redhat.com>
+Date: Tue, 15 Feb 2022 10:59:00 +0100
+Subject: [PATCH 2/2] io: Unset dev_handle when removing transfer from flying
+ list
+
+API users might hold on to transfers a bit longer than they are in the
+flying list. If they then close the device prior to freeing all
+transfers, we would end up with invalid pointers to the device.
+
+Fix this by setting the device handle to NULL when removing the device
+from the flying list. This matches the behaviour when the device is
+closed while the transfer is still in the flying list.
+
+Specifically, the libgusb wrapper will currently only free the
+underlying transfer in a later mainloop iteration (as a side effect on
+how GTask does memory management). It is possible to fix this, but it
+would make memory management within libgusb much more error prone.
+---
+ libusb/io.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/libusb/io.c b/libusb/io.c
+index 0d2ac9ea..4e6d8984 100644
+--- a/libusb/io.c
++++ b/libusb/io.c
+@@ -1456,6 +1456,7 @@ static int add_to_flying_list(struct usbi_transfer *itransfer)
+  * if it fails to update the timer for the next timeout. */
+ static int remove_from_flying_list(struct usbi_transfer *itransfer)
+ {
++	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
+ 	struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
+ 	int rearm_timer;
+ 	int r = 0;
+@@ -1466,6 +1467,7 @@ static int remove_from_flying_list(struct usbi_transfer *itransfer)
+ 	list_del(&itransfer->list);
+ 	if (rearm_timer)
+ 		r = arm_timer_for_next_timeout(ctx);
++	transfer->dev_handle = NULL;
+ 	usbi_mutex_unlock(&ctx->flying_transfers_lock);
+ 
+ 	return r;
diff --git a/SPECS/libusbx.spec b/SPECS/libusbx.spec
index 83e7679..08883a1 100644
--- a/SPECS/libusbx.spec
+++ b/SPECS/libusbx.spec
@@ -1,7 +1,7 @@
 Summary:        Library for accessing USB devices
 Name:           libusbx
-Version:        1.0.24
-Release:        4%{?dist}
+Version:        1.0.25
+Release:        2%{?dist}
 # upstream libusbx has merged back with libusb and is now called libusb again
 # but we already have a libusb package for the old libusb-compat-0.1, renaming
 # that to libusb-compat while at the same time giving this its name is a bit
@@ -14,9 +14,14 @@ BuildRequires: make
 Provides:       libusb1 = %{version}-%{release}
 Obsoletes:      libusb1 <= 1.0.9
 
-Patch001:       0001-linux_usbfs-Accept-sysfs-attributes-not-terminated-w.patch
-Patch002:       0001-linux_usbfs-Fix-parsing-of-descriptors-for-multi-con.patch
-Patch003:       0002-linux_usbfs-Gracefully-handle-buggy-devices-with-a-c.patch
+# 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
+
+# Pull in coverity related fixes
+Patch9999:      https://github.com/libusb/libusb/pull/1067.patch
 
 %description
 This package provides a way for applications to access USB devices.
@@ -123,6 +128,16 @@ LD_LIBRARY_PATH=libusb/.libs $RPM_BUILD_ROOT%{_bindir}/libusb-example-listdevs
 
 
 %changelog
+* Tue Feb 15 2022 Benjamin Berg <bberg@redhat.com> - 1.0.25-2
+- Fix a crash if a transfer outlives closing the device
+  Related: #1938801
+
+* Thu Feb 10 2022 Benjamin Berg <bberg@redhat.com> - 1.0.25-1
+- Update to 1.0.25
+- Fix a crash after libusb_exit API has been misused
+- Add patchset to fix covscan reports
+  Resolves: #1938801
+
 * Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 1.0.24-4
 - Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
   Related: rhbz#1991688