Blame SOURCES/1067.patch

46a7df
From 20b8e95bfc3a9c1be1752e65043a8ed9445fbbd2 Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Thu, 15 Jul 2021 17:07:09 +0200
46a7df
Subject: [PATCH 01/18] examples: Fix warning about uninitlised variable
46a7df
46a7df
---
46a7df
 examples/fxload.c | 3 ++-
46a7df
 1 file changed, 2 insertions(+), 1 deletion(-)
46a7df
46a7df
diff --git a/examples/fxload.c b/examples/fxload.c
46a7df
index 541c3d3a3..85df69952 100644
46a7df
--- a/examples/fxload.c
46a7df
+++ b/examples/fxload.c
46a7df
@@ -87,7 +87,8 @@ int main(int argc, char*argv[])
46a7df
 	const char *type = NULL;
46a7df
 	const char *fx_name[FX_TYPE_MAX] = FX_TYPE_NAMES;
46a7df
 	const char *ext, *img_name[] = IMG_TYPE_NAMES;
46a7df
-	int fx_type = FX_TYPE_UNDEFINED, img_type[ARRAYSIZE(path)];
46a7df
+	int fx_type = FX_TYPE_UNDEFINED;
46a7df
+	int img_type[ARRAYSIZE(path)] = { IMG_TYPE_UNDEFINED, IMG_TYPE_UNDEFINED };
46a7df
 	int opt, status;
46a7df
 	unsigned int i, j;
46a7df
 	unsigned vid = 0, pid = 0;
46a7df
46a7df
From 0803cdc46314c70ad7f12a7c2d0b1df5b028a89d Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Thu, 15 Jul 2021 17:08:12 +0200
46a7df
Subject: [PATCH 02/18] core: Add non-null annotations to avoid static analyser
46a7df
 warnings
46a7df
46a7df
It is only valid to call these inline functions with non-null values.
46a7df
However, static analysis may complain that the functions may dereference
46a7df
the pointer incorrectly if it is only looking at the function itself
46a7df
rather than including the surrounding code.
46a7df
46a7df
Add the appropriate annotiations to both fix warnings and improve
46a7df
detection of bugs in API users.
46a7df
---
46a7df
 libusb/libusb.h  | 13 +++++++++++++
46a7df
 libusb/libusbi.h | 14 ++++++++++----
46a7df
 2 files changed, 23 insertions(+), 4 deletions(-)
46a7df
46a7df
diff --git a/libusb/libusb.h b/libusb/libusb.h
46a7df
index 61cacc95a..ea09fa8d9 100644
46a7df
--- a/libusb/libusb.h
46a7df
+++ b/libusb/libusb.h
46a7df
@@ -77,8 +77,10 @@ typedef SSIZE_T ssize_t;
46a7df
 
46a7df
 #if defined(__GNUC__)
46a7df
 #define LIBUSB_PACKED __attribute__ ((packed))
46a7df
+#define LIBUSB_NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
46a7df
 #else
46a7df
 #define LIBUSB_PACKED
46a7df
+#define LIBUSB_NONNULL(...)
46a7df
 #endif /* __GNUC__ */
46a7df
 
46a7df
 /** \def LIBUSB_CALL
46a7df
@@ -1479,6 +1481,7 @@ int LIBUSB_CALL libusb_set_auto_detach_kernel_driver(
46a7df
  * \param transfer a transfer
46a7df
  * \returns pointer to the first byte of the data section
46a7df
  */
46a7df
+LIBUSB_NONNULL(1)
46a7df
 static inline unsigned char *libusb_control_transfer_get_data(
46a7df
 	struct libusb_transfer *transfer)
46a7df
 {
46a7df
@@ -1497,6 +1500,7 @@ static inline unsigned char *libusb_control_transfer_get_data(
46a7df
  * \param transfer a transfer
46a7df
  * \returns a casted pointer to the start of the transfer data buffer
46a7df
  */
46a7df
+LIBUSB_NONNULL(1)
46a7df
 static inline struct libusb_control_setup *libusb_control_transfer_get_setup(
46a7df
 	struct libusb_transfer *transfer)
46a7df
 {
46a7df
@@ -1526,6 +1530,7 @@ static inline struct libusb_control_setup *libusb_control_transfer_get_setup(
46a7df
  * \ref libusb_control_setup::wLength "wLength" field of
46a7df
  * \ref libusb_control_setup
46a7df
  */
46a7df
+LIBUSB_NONNULL(1)
46a7df
 static inline void libusb_fill_control_setup(unsigned char *buffer,
46a7df
 	uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
46a7df
 	uint16_t wLength)
46a7df
@@ -1575,6 +1580,7 @@ uint32_t LIBUSB_CALL libusb_transfer_get_stream_id(
46a7df
  * \param user_data user data to pass to callback function
46a7df
  * \param timeout timeout for the transfer in milliseconds
46a7df
  */
46a7df
+LIBUSB_NONNULL(1)
46a7df
 static inline void libusb_fill_control_transfer(
46a7df
 	struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
46a7df
 	unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data,
46a7df
@@ -1606,6 +1612,7 @@ static inline void libusb_fill_control_transfer(
46a7df
  * \param user_data user data to pass to callback function
46a7df
  * \param timeout timeout for the transfer in milliseconds
46a7df
  */
46a7df
+LIBUSB_NONNULL(1)
46a7df
 static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer,
46a7df
 	libusb_device_handle *dev_handle, unsigned char endpoint,
46a7df
 	unsigned char *buffer, int length, libusb_transfer_cb_fn callback,
46a7df
@@ -1637,6 +1644,7 @@ static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer,
46a7df
  * \param user_data user data to pass to callback function
46a7df
  * \param timeout timeout for the transfer in milliseconds
46a7df
  */
46a7df
+LIBUSB_NONNULL(1)
46a7df
 static inline void libusb_fill_bulk_stream_transfer(
46a7df
 	struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
46a7df
 	unsigned char endpoint, uint32_t stream_id,
46a7df
@@ -1662,6 +1670,7 @@ static inline void libusb_fill_bulk_stream_transfer(
46a7df
  * \param user_data user data to pass to callback function
46a7df
  * \param timeout timeout for the transfer in milliseconds
46a7df
  */
46a7df
+LIBUSB_NONNULL(1)
46a7df
 static inline void libusb_fill_interrupt_transfer(
46a7df
 	struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
46a7df
 	unsigned char endpoint, unsigned char *buffer, int length,
46a7df
@@ -1691,6 +1700,7 @@ static inline void libusb_fill_interrupt_transfer(
46a7df
  * \param user_data user data to pass to callback function
46a7df
  * \param timeout timeout for the transfer in milliseconds
46a7df
  */
46a7df
+LIBUSB_NONNULL(1)
46a7df
 static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer,
46a7df
 	libusb_device_handle *dev_handle, unsigned char endpoint,
46a7df
 	unsigned char *buffer, int length, int num_iso_packets,
46a7df
@@ -1715,6 +1725,7 @@ static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer,
46a7df
  * \param length the length to set in each isochronous packet descriptor
46a7df
  * \see libusb_get_max_packet_size()
46a7df
  */
46a7df
+LIBUSB_NONNULL(1)
46a7df
 static inline void libusb_set_iso_packet_lengths(
46a7df
 	struct libusb_transfer *transfer, unsigned int length)
46a7df
 {
46a7df
@@ -1740,6 +1751,7 @@ static inline void libusb_set_iso_packet_lengths(
46a7df
  * or NULL if the packet does not exist.
46a7df
  * \see libusb_get_iso_packet_buffer_simple()
46a7df
  */
46a7df
+LIBUSB_NONNULL(1)
46a7df
 static inline unsigned char *libusb_get_iso_packet_buffer(
46a7df
 	struct libusb_transfer *transfer, unsigned int packet)
46a7df
 {
46a7df
@@ -1782,6 +1794,7 @@ static inline unsigned char *libusb_get_iso_packet_buffer(
46a7df
  * or NULL if the packet does not exist.
46a7df
  * \see libusb_get_iso_packet_buffer()
46a7df
  */
46a7df
+LIBUSB_NONNULL(1)
46a7df
 static inline unsigned char *libusb_get_iso_packet_buffer_simple(
46a7df
 	struct libusb_transfer *transfer, unsigned int packet)
46a7df
 {
46a7df
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
46a7df
index b1fc88c99..db074160c 100644
46a7df
--- a/libusb/libusbi.h
46a7df
+++ b/libusb/libusbi.h
46a7df
@@ -192,11 +192,13 @@ struct list_head {
46a7df
 
46a7df
 #define list_empty(entry) ((entry)->next == (entry))
46a7df
 
46a7df
+LIBUSB_NONNULL(1)
46a7df
 static inline void list_init(struct list_head *entry)
46a7df
 {
46a7df
 	entry->prev = entry->next = entry;
46a7df
 }
46a7df
 
46a7df
+LIBUSB_NONNULL(1, 2)
46a7df
 static inline void list_add(struct list_head *entry, struct list_head *head)
46a7df
 {
46a7df
 	entry->next = head->next;
46a7df
@@ -206,6 +208,7 @@ static inline void list_add(struct list_head *entry, struct list_head *head)
46a7df
 	head->next = entry;
46a7df
 }
46a7df
 
46a7df
+LIBUSB_NONNULL(1, 2)
46a7df
 static inline void list_add_tail(struct list_head *entry,
46a7df
 	struct list_head *head)
46a7df
 {
46a7df
@@ -216,6 +219,7 @@ static inline void list_add_tail(struct list_head *entry,
46a7df
 	head->prev = entry;
46a7df
 }
46a7df
 
46a7df
+LIBUSB_NONNULL(1)
46a7df
 static inline void list_del(struct list_head *entry)
46a7df
 {
46a7df
 	entry->next->prev = entry->prev;
46a7df
@@ -223,6 +227,7 @@ static inline void list_del(struct list_head *entry)
46a7df
 	entry->next = entry->prev = NULL;
46a7df
 }
46a7df
 
46a7df
+LIBUSB_NONNULL(1, 2)
46a7df
 static inline void list_cut(struct list_head *list, struct list_head *head)
46a7df
 {
46a7df
 	if (list_empty(head)) {
46a7df
@@ -773,10 +778,10 @@ struct usbi_hotplug_message {
46a7df
 
46a7df
 /* shared data and functions */
46a7df
 
46a7df
-void usbi_hotplug_init(struct libusb_context *ctx);
46a7df
-void usbi_hotplug_exit(struct libusb_context *ctx);
46a7df
+void usbi_hotplug_init(struct libusb_context *ctx) LIBUSB_NONNULL(1);
46a7df
+void usbi_hotplug_exit(struct libusb_context *ctx) LIBUSB_NONNULL(1);
46a7df
 void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev,
46a7df
-	libusb_hotplug_event event);
46a7df
+	libusb_hotplug_event event) LIBUSB_NONNULL(1);
46a7df
 void usbi_hotplug_process(struct libusb_context *ctx, struct list_head *hotplug_msgs);
46a7df
 
46a7df
 int usbi_io_init(struct libusb_context *ctx);
46a7df
@@ -807,7 +812,8 @@ struct usbi_event_source {
46a7df
 
46a7df
 int usbi_add_event_source(struct libusb_context *ctx, usbi_os_handle_t os_handle,
46a7df
 	short poll_events);
46a7df
-void usbi_remove_event_source(struct libusb_context *ctx, usbi_os_handle_t os_handle);
46a7df
+void usbi_remove_event_source(struct libusb_context *ctx, usbi_os_handle_t os_handle)
46a7df
+	LIBUSB_NONNULL(1);
46a7df
 
46a7df
 struct usbi_option {
46a7df
   int is_set;
46a7df
46a7df
From 3ba52d0d048214ee530c2343260965724291255a Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Wed, 9 Feb 2022 19:21:09 +0100
46a7df
Subject: [PATCH 03/18] core: Silence dereference warnings using assertions in
46a7df
 list_del
46a7df
46a7df
It is guaranteed that entry->next and entry->prev are non-null for a
46a7df
list item that is part of a list. The static analyser might be confused
46a7df
though, so add an appropriate assert in case debug mode is enabled.
46a7df
---
46a7df
 libusb/libusbi.h | 4 ++++
46a7df
 1 file changed, 4 insertions(+)
46a7df
46a7df
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
46a7df
index db074160c..27de77aa9 100644
46a7df
--- a/libusb/libusbi.h
46a7df
+++ b/libusb/libusbi.h
46a7df
@@ -222,6 +222,10 @@ static inline void list_add_tail(struct list_head *entry,
46a7df
 LIBUSB_NONNULL(1)
46a7df
 static inline void list_del(struct list_head *entry)
46a7df
 {
46a7df
+#ifndef NDEBUG
46a7df
+	assert(entry->next && entry->prev);
46a7df
+#endif
46a7df
+
46a7df
 	entry->next->prev = entry->prev;
46a7df
 	entry->prev->next = entry->next;
46a7df
 	entry->next = entry->prev = NULL;
46a7df
46a7df
From 70486056d5668c94ea3a1824541ff2f36f378d3e Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Thu, 15 Jul 2021 17:11:41 +0200
46a7df
Subject: [PATCH 04/18] core: Fix incorrect free if reallocating to zero size
46a7df
46a7df
A realloc to a size of 0 is equivalent to a free call. As such, in that
46a7df
case free'ing the original pointer would result in a double free. Fix
46a7df
this by adding a check that the new size if larger than zero.
46a7df
---
46a7df
 libusb/libusbi.h | 9 ++++++++-
46a7df
 1 file changed, 8 insertions(+), 1 deletion(-)
46a7df
46a7df
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
46a7df
index 27de77aa9..dabf77a9d 100644
46a7df
--- a/libusb/libusbi.h
46a7df
+++ b/libusb/libusbi.h
46a7df
@@ -257,7 +257,14 @@ static inline void list_splice_front(struct list_head *list, struct list_head *h
46a7df
 
46a7df
 static inline void *usbi_reallocf(void *ptr, size_t size)
46a7df
 {
46a7df
-	void *ret = realloc(ptr, size);
46a7df
+	void *ret;
46a7df
+
46a7df
+	if (size == 0) {
46a7df
+		free(ptr);
46a7df
+		return NULL;
46a7df
+	}
46a7df
+
46a7df
+	ret = realloc(ptr, size);
46a7df
 
46a7df
 	if (!ret)
46a7df
 		free(ptr);
46a7df
46a7df
From 73f565261d9284d9f6b0081e3e23fd49773f53c7 Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Thu, 15 Jul 2021 17:13:18 +0200
46a7df
Subject: [PATCH 05/18] linux_usbfs: Work around static analyser thinking fd is
46a7df
 leaked
46a7df
46a7df
Static analysis using coverity is detecting the file descriptor handle
46a7df
potentially being leaked in some situations. The code itself is actually
46a7df
sound, but coverity is not correctly following the fact that fd can be
46a7df
compared against wrapped_fd.
46a7df
46a7df
Fix this by introducing an fd_close variable which is compared to a
46a7df
fixed value to decide whether to close the fd. Also switch to a goto
46a7df
pattern rather than returning from different places.
46a7df
---
46a7df
 libusb/os/linux_usbfs.c | 51 ++++++++++++++++++++++++-----------------
46a7df
 1 file changed, 30 insertions(+), 21 deletions(-)
46a7df
46a7df
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
46a7df
index 285d9caa7..1799a9ea0 100644
46a7df
--- a/libusb/os/linux_usbfs.c
46a7df
+++ b/libusb/os/linux_usbfs.c
46a7df
@@ -904,7 +904,8 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
46a7df
 	struct linux_device_priv *priv = usbi_get_device_priv(dev);
46a7df
 	struct libusb_context *ctx = DEVICE_CTX(dev);
46a7df
 	size_t alloc_len;
46a7df
-	int fd, speed, r;
46a7df
+	int fd, fd_close = -1;
46a7df
+	int speed, r;
46a7df
 	ssize_t nb;
46a7df
 
46a7df
 	dev->bus_number = busnum;
46a7df
@@ -934,19 +935,22 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
46a7df
 
46a7df
 	/* cache descriptors in memory */
46a7df
 	if (sysfs_dir) {
46a7df
-		fd = open_sysfs_attr(ctx, sysfs_dir, "descriptors");
46a7df
+		fd = fd_close = open_sysfs_attr(ctx, sysfs_dir, "descriptors");
46a7df
 	} else if (wrapped_fd < 0) {
46a7df
-		fd = get_usbfs_fd(dev, O_RDONLY, 0);
46a7df
+		fd = fd_close = get_usbfs_fd(dev, O_RDONLY, 0);
46a7df
 	} else {
46a7df
 		fd = wrapped_fd;
46a7df
 		r = lseek(fd, 0, SEEK_SET);
46a7df
 		if (r < 0) {
46a7df
 			usbi_err(ctx, "lseek failed, errno=%d", errno);
46a7df
-			return LIBUSB_ERROR_IO;
46a7df
+			r = LIBUSB_ERROR_IO;
46a7df
+			goto out;
46a7df
 		}
46a7df
 	}
46a7df
-	if (fd < 0)
46a7df
-		return fd;
46a7df
+	if (fd < 0) {
46a7df
+		r = fd;
46a7df
+		goto out;
46a7df
+	}
46a7df
 
46a7df
 	alloc_len = 0;
46a7df
 	do {
46a7df
@@ -956,9 +960,8 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
46a7df
 		alloc_len += desc_read_length;
46a7df
 		priv->descriptors = usbi_reallocf(priv->descriptors, alloc_len);
46a7df
 		if (!priv->descriptors) {
46a7df
-			if (fd != wrapped_fd)
46a7df
-				close(fd);
46a7df
-			return LIBUSB_ERROR_NO_MEM;
46a7df
+			r = LIBUSB_ERROR_NO_MEM;
46a7df
+			goto out;
46a7df
 		}
46a7df
 		read_ptr = (uint8_t *)priv->descriptors + priv->descriptors_len;
46a7df
 		/* usbfs has holes in the file */
46a7df
@@ -967,36 +970,39 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
46a7df
 		nb = read(fd, read_ptr, desc_read_length);
46a7df
 		if (nb < 0) {
46a7df
 			usbi_err(ctx, "read descriptor failed, errno=%d", errno);
46a7df
-			if (fd != wrapped_fd)
46a7df
-				close(fd);
46a7df
-			return LIBUSB_ERROR_IO;
46a7df
+			r = LIBUSB_ERROR_IO;
46a7df
+			goto out;
46a7df
 		}
46a7df
 		priv->descriptors_len += (size_t)nb;
46a7df
 	} while (priv->descriptors_len == alloc_len);
46a7df
 
46a7df
-	if (fd != wrapped_fd)
46a7df
-		close(fd);
46a7df
+	if (fd_close >= 0) {
46a7df
+		close(fd_close);
46a7df
+		fd_close = -1;
46a7df
+	}
46a7df
 
46a7df
 	if (priv->descriptors_len < LIBUSB_DT_DEVICE_SIZE) {
46a7df
 		usbi_err(ctx, "short descriptor read (%zu)", priv->descriptors_len);
46a7df
-		return LIBUSB_ERROR_IO;
46a7df
+		r = LIBUSB_ERROR_IO;
46a7df
+		goto out;
46a7df
 	}
46a7df
 
46a7df
 	r = parse_config_descriptors(dev);
46a7df
 	if (r < 0)
46a7df
-		return r;
46a7df
+		goto out;
46a7df
 
46a7df
 	memcpy(&dev->device_descriptor, priv->descriptors, LIBUSB_DT_DEVICE_SIZE);
46a7df
 
46a7df
 	if (sysfs_dir) {
46a7df
 		/* sysfs descriptors are in bus-endian format */
46a7df
 		usbi_localize_device_descriptor(&dev->device_descriptor);
46a7df
-		return LIBUSB_SUCCESS;
46a7df
+		r = LIBUSB_SUCCESS;
46a7df
+		goto out;
46a7df
 	}
46a7df
 
46a7df
 	/* cache active config */
46a7df
 	if (wrapped_fd < 0)
46a7df
-		fd = get_usbfs_fd(dev, O_RDWR, 1);
46a7df
+		fd = fd_close = get_usbfs_fd(dev, O_RDWR, 1);
46a7df
 	else
46a7df
 		fd = wrapped_fd;
46a7df
 	if (fd < 0) {
46a7df
@@ -1009,12 +1015,15 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum,
46a7df
 		else
46a7df
 			priv->active_config = -1; /* No config dt */
46a7df
 
46a7df
-		return LIBUSB_SUCCESS;
46a7df
+		r = LIBUSB_SUCCESS;
46a7df
+		goto out;
46a7df
 	}
46a7df
 
46a7df
 	r = usbfs_get_active_config(dev, fd);
46a7df
-	if (fd != wrapped_fd)
46a7df
-		close(fd);
46a7df
+
46a7df
+out:
46a7df
+	if (fd_close >= 0)
46a7df
+		close(fd_close);
46a7df
 
46a7df
 	return r;
46a7df
 }
46a7df
46a7df
From f6cc8938c5ccf3556cfa54fe8e1d26e627995731 Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Wed, 9 Feb 2022 19:08:31 +0100
46a7df
Subject: [PATCH 06/18] examples: Fix warning about NULL pointer dereference
46a7df
46a7df
It seems like coverity is getting confused by the transfers being global
46a7df
variables, thinking that img_transfer may become NULL again.
46a7df
46a7df
Fix this bogus warning by moving the check down.
46a7df
---
46a7df
 examples/dpfp.c | 7 +------
46a7df
 1 file changed, 1 insertion(+), 6 deletions(-)
46a7df
46a7df
diff --git a/examples/dpfp.c b/examples/dpfp.c
46a7df
index 682865053..4a871ee4f 100644
46a7df
--- a/examples/dpfp.c
46a7df
+++ b/examples/dpfp.c
46a7df
@@ -554,13 +554,8 @@ static int do_init(void)
46a7df
 static int alloc_transfers(void)
46a7df
 {
46a7df
 	img_transfer = libusb_alloc_transfer(0);
46a7df
-	if (!img_transfer) {
46a7df
-		errno = ENOMEM;
46a7df
-		return -1;
46a7df
-	}
46a7df
-
46a7df
 	irq_transfer = libusb_alloc_transfer(0);
46a7df
-	if (!irq_transfer) {
46a7df
+	if (!img_transfer || !irq_transfer) {
46a7df
 		errno = ENOMEM;
46a7df
 		return -1;
46a7df
 	}
46a7df
46a7df
From c2257799e48351e4ac09bb40794f3c8559d93459 Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Wed, 9 Feb 2022 19:09:53 +0100
46a7df
Subject: [PATCH 07/18] examples: Assert the data fits into our static buffer
46a7df
46a7df
---
46a7df
 examples/ezusb.c | 2 ++
46a7df
 1 file changed, 2 insertions(+)
46a7df
46a7df
diff --git a/examples/ezusb.c b/examples/ezusb.c
46a7df
index 4bed12a4c..0ea787190 100644
46a7df
--- a/examples/ezusb.c
46a7df
+++ b/examples/ezusb.c
46a7df
@@ -23,6 +23,7 @@
46a7df
 
46a7df
 #include <config.h>
46a7df
 
46a7df
+#include <assert.h>
46a7df
 #include <stdio.h>
46a7df
 #include <errno.h>
46a7df
 #include <stdlib.h>
46a7df
@@ -303,6 +304,7 @@ static int parse_ihex(FILE *image, void *context,
46a7df
 		buf[3] = 0;
46a7df
 		len = strtoul(buf+1, NULL, 16);
46a7df
 		buf[3] = tmp;
46a7df
+		assert(len <= sizeof(data));
46a7df
 
46a7df
 		/* Read the target offset (address up to 64KB) */
46a7df
 		tmp = buf[7];
46a7df
46a7df
From 9bd8bca34de151e191db4d33d717a36488f9a96e Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Wed, 9 Feb 2022 19:11:28 +0100
46a7df
Subject: [PATCH 08/18] core: Tell coverity that libusb_open does not free
46a7df
46a7df
Internally, libusb_open does an unref in an error case. coverity doesn't
46a7df
seem to notice that this is balanced with the earlier ref, and thinks
46a7df
that the passed in device may be free'ed. Annotate the function to
46a7df
prevent misdetections.
46a7df
46a7df
An alternative would be to only take the reference after checking for
46a7df
the error, but the code is idiomatic as-is.
46a7df
---
46a7df
 libusb/core.c | 1 +
46a7df
 1 file changed, 1 insertion(+)
46a7df
46a7df
diff --git a/libusb/core.c b/libusb/core.c
46a7df
index ec429b7cf..b9bf844ee 100644
46a7df
--- a/libusb/core.c
46a7df
+++ b/libusb/core.c
46a7df
@@ -1294,6 +1294,7 @@ int API_EXPORTED libusb_wrap_sys_device(libusb_context *ctx, intptr_t sys_dev,
46a7df
  * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
46a7df
  * \returns another LIBUSB_ERROR code on other failure
46a7df
  */
46a7df
+/* coverity[-free: arg-0] false positive due to error handling path */
46a7df
 int API_EXPORTED libusb_open(libusb_device *dev,
46a7df
 	libusb_device_handle **dev_handle)
46a7df
 {
46a7df
46a7df
From 88e1269900cb8a581d6335d758b713d71ecd8d8e Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Wed, 9 Feb 2022 19:13:26 +0100
46a7df
Subject: [PATCH 09/18] core: Remove unneeded bounds check
46a7df
46a7df
This makes the code slightly less efficient, but shuts up warnings that
46a7df
the later switch ends up with dead error handling code.
46a7df
---
46a7df
 libusb/core.c | 4 ----
46a7df
 1 file changed, 4 deletions(-)
46a7df
46a7df
diff --git a/libusb/core.c b/libusb/core.c
46a7df
index b9bf844ee..1643f9334 100644
46a7df
--- a/libusb/core.c
46a7df
+++ b/libusb/core.c
46a7df
@@ -2202,10 +2202,6 @@ int API_EXPORTED libusb_set_option(libusb_context *ctx,
46a7df
 		return r;
46a7df
 	}
46a7df
 
46a7df
-	if (option >= LIBUSB_OPTION_MAX) {
46a7df
-		return LIBUSB_ERROR_INVALID_PARAM;
46a7df
-	}
46a7df
-
46a7df
 	if (NULL == ctx) {
46a7df
 		usbi_mutex_static_lock(&default_context_lock);
46a7df
 		default_context_options[option].is_set = 1;
46a7df
46a7df
From 1eb546e65aaca0c47615a275a961bbeb123c838e Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Wed, 9 Feb 2022 19:15:16 +0100
46a7df
Subject: [PATCH 10/18] descriptor: Avoid uninitialized memory warnings
46a7df
46a7df
The static analyzer has trouble understanding that get_config_descriptor
46a7df
fills in the config descriptor. Just initializing the memory silences
46a7df
the warning and is safe to do.
46a7df
---
46a7df
 libusb/descriptor.c | 4 ++--
46a7df
 1 file changed, 2 insertions(+), 2 deletions(-)
46a7df
46a7df
diff --git a/libusb/descriptor.c b/libusb/descriptor.c
46a7df
index 253ef1c31..dbcf061d9 100644
46a7df
--- a/libusb/descriptor.c
46a7df
+++ b/libusb/descriptor.c
46a7df
@@ -555,7 +555,7 @@ int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
46a7df
 int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev,
46a7df
 	struct libusb_config_descriptor **config)
46a7df
 {
46a7df
-	union usbi_config_desc_buf _config;
46a7df
+	union usbi_config_desc_buf _config = { 0, };
46a7df
 	uint16_t config_len;
46a7df
 	uint8_t *buf;
46a7df
 	int r;
46a7df
@@ -658,7 +658,7 @@ int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev,
46a7df
 
46a7df
 	usbi_dbg(DEVICE_CTX(dev), "value %u", bConfigurationValue);
46a7df
 	for (idx = 0; idx < dev->device_descriptor.bNumConfigurations; idx++) {
46a7df
-		union usbi_config_desc_buf _config;
46a7df
+		union usbi_config_desc_buf _config = { 0, };
46a7df
 
46a7df
 		r = get_config_descriptor(dev, idx, _config.buf, sizeof(_config.buf));
46a7df
 		if (r < 0)
46a7df
46a7df
From 0de57c4af4e637a0a8adfda9a907774add81c8ec Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Wed, 9 Feb 2022 19:19:04 +0100
46a7df
Subject: [PATCH 11/18] io: Suppress invalid free warning from coverity
46a7df
46a7df
Coverity is not understanding the pointer arithmetic involved with the
46a7df
transfer in-memory storage. As such, it flags the free as invalid, even
46a7df
though everything is fine. Add an appropriate comment to silence the
46a7df
warning.
46a7df
---
46a7df
 libusb/io.c | 4 +++-
46a7df
 1 file changed, 3 insertions(+), 1 deletion(-)
46a7df
46a7df
diff --git a/libusb/io.c b/libusb/io.c
46a7df
index b919e9d91..a801ee6aa 100644
46a7df
--- a/libusb/io.c
46a7df
+++ b/libusb/io.c
46a7df
@@ -1696,8 +1696,10 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
46a7df
 		transfer->callback(transfer);
46a7df
 	/* transfer might have been freed by the above call, do not use from
46a7df
 	 * this point. */
46a7df
-	if (flags & LIBUSB_TRANSFER_FREE_TRANSFER)
46a7df
+	if (flags & LIBUSB_TRANSFER_FREE_TRANSFER) {
46a7df
+		/* coverity[incorrect_free] is reported incorrectly here due to the memory layout */
46a7df
 		libusb_free_transfer(transfer);
46a7df
+	}
46a7df
 	return r;
46a7df
 }
46a7df
 
46a7df
46a7df
From 5dad238771240a6aa8234ba42511fb422c79800c Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Wed, 9 Feb 2022 19:20:27 +0100
46a7df
Subject: [PATCH 12/18] io: Suppress missing unlock warning from coverity
46a7df
46a7df
The function is supposed to take the lock, as such, this is the expected
46a7df
behaviour.
46a7df
---
46a7df
 libusb/io.c | 1 +
46a7df
 1 file changed, 1 insertion(+)
46a7df
46a7df
diff --git a/libusb/io.c b/libusb/io.c
46a7df
index a801ee6aa..114087d94 100644
46a7df
--- a/libusb/io.c
46a7df
+++ b/libusb/io.c
46a7df
@@ -1790,6 +1790,7 @@ int API_EXPORTED libusb_try_lock_events(libusb_context *ctx)
46a7df
 		return 1;
46a7df
 
46a7df
 	ctx->event_handler_active = 1;
46a7df
+	/* coverity[missing_unlock] is expected here */
46a7df
 	return 0;
46a7df
 }
46a7df
 
46a7df
46a7df
From 884b55a36ae4dfae6fda1120c948bcf17a333b95 Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Wed, 9 Feb 2022 19:23:45 +0100
46a7df
Subject: [PATCH 13/18] events_posix: Silence warnings about zero-allocated
46a7df
 memory
46a7df
46a7df
The static analyser got confused by the fact that fds may be NULL if
46a7df
there are no event sources. Obviously, in that case the later loop that
46a7df
dereferences fds will never do anything, but coverity seems to miss that
46a7df
part.
46a7df
46a7df
Silence the warning by doing an early return from the function.
46a7df
---
46a7df
 libusb/os/events_posix.c | 4 ++++
46a7df
 1 file changed, 4 insertions(+)
46a7df
46a7df
diff --git a/libusb/os/events_posix.c b/libusb/os/events_posix.c
46a7df
index 715a2d551..172f8afe8 100644
46a7df
--- a/libusb/os/events_posix.c
46a7df
+++ b/libusb/os/events_posix.c
46a7df
@@ -201,6 +201,10 @@ int usbi_alloc_event_data(struct libusb_context *ctx)
46a7df
 	for_each_event_source(ctx, ievent_source)
46a7df
 		ctx->event_data_cnt++;
46a7df
 
46a7df
+	/* Silence warning about use of zero allocated memory. */
46a7df
+	if (ctx->event_data_cnt == 0)
46a7df
+		return 0;
46a7df
+
46a7df
 	fds = calloc(ctx->event_data_cnt, sizeof(*fds));
46a7df
 	if (!fds)
46a7df
 		return LIBUSB_ERROR_NO_MEM;
46a7df
46a7df
From 4e2589b2e9981e5213fb4267550c10638f758add Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Wed, 9 Feb 2022 19:25:40 +0100
46a7df
Subject: [PATCH 14/18] linux_usbfs: Disable sleep workaround when using udev
46a7df
46a7df
The workaround to sleep 10ms if a device node has not yet been created
46a7df
is definitely not needed with udev. I am not sure what the race looks
46a7df
like in the netlink case, unless some other userspace daemon (udev) is
46a7df
reacting to the same message and creates the device.
46a7df
46a7df
I suppose, in the long run this might be fixed by removing the netlink
46a7df
code.
46a7df
---
46a7df
 libusb/os/linux_usbfs.c | 3 +++
46a7df
 1 file changed, 3 insertions(+)
46a7df
46a7df
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
46a7df
index 1799a9ea0..481eff6ef 100644
46a7df
--- a/libusb/os/linux_usbfs.c
46a7df
+++ b/libusb/os/linux_usbfs.c
46a7df
@@ -197,6 +197,8 @@ static int get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
46a7df
 	if (fd != -1)
46a7df
 		return fd; /* Success */
46a7df
 
46a7df
+/* This workaround is only relevant when watching netlink directly rather than udev. */
46a7df
+#if !defined(HAVE_LIBUDEV)
46a7df
 	if (errno == ENOENT) {
46a7df
 		const long delay_ms = 10L;
46a7df
 		const struct timespec delay_ts = { 0L, delay_ms * 1000L * 1000L };
46a7df
@@ -211,6 +213,7 @@ static int get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent)
46a7df
 		if (fd != -1)
46a7df
 			return fd; /* Success */
46a7df
 	}
46a7df
+#endif
46a7df
 
46a7df
 	if (!silent) {
46a7df
 		usbi_err(ctx, "libusb couldn't open USB device %s, errno=%d", path, errno);
46a7df
46a7df
From d237b8cca6c33e237da69ee096232d216f9202a8 Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Wed, 9 Feb 2022 19:29:35 +0100
46a7df
Subject: [PATCH 15/18] linux_usbfs: Silence coverity warnings about returned
46a7df
 offset
46a7df
46a7df
The seek_to_next_config function returns an offset. This was marked as
46a7df
tained by coverity, but really, we can trust it to be OK in the
46a7df
surrounding code. Mark the return value to silence the warnings.
46a7df
---
46a7df
 libusb/os/linux_usbfs.c | 1 +
46a7df
 1 file changed, 1 insertion(+)
46a7df
46a7df
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
46a7df
index 481eff6ef..d95ed3bea 100644
46a7df
--- a/libusb/os/linux_usbfs.c
46a7df
+++ b/libusb/os/linux_usbfs.c
46a7df
@@ -638,6 +638,7 @@ int linux_get_device_address(struct libusb_context *ctx, int detached,
46a7df
 }
46a7df
 
46a7df
 /* Return offset of the next config descriptor */
46a7df
+/* coverity[-taint_source] as the returned offset can be trusted */
46a7df
 static int seek_to_next_config(struct libusb_context *ctx,
46a7df
 	uint8_t *buffer, size_t len)
46a7df
 {
46a7df
46a7df
From ea73414f3309a908d2819991580b080cabca17eb Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Wed, 9 Feb 2022 19:31:44 +0100
46a7df
Subject: [PATCH 16/18] linux_usbfs: Silence coverity warning about missing
46a7df
 locking
46a7df
46a7df
The reap_status field is locked in most cases when it is accessed.
46a7df
This causes a warning from coverity, however locking is not needed in
46a7df
this particular case as the transfer has not yet been submitted.
46a7df
46a7df
As such, add an appropriate comment to silence the warning.
46a7df
---
46a7df
 libusb/os/linux_usbfs.c | 1 +
46a7df
 1 file changed, 1 insertion(+)
46a7df
46a7df
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
46a7df
index d95ed3bea..35cc54ab5 100644
46a7df
--- a/libusb/os/linux_usbfs.c
46a7df
+++ b/libusb/os/linux_usbfs.c
46a7df
@@ -1984,6 +1984,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
46a7df
 	tpriv->num_urbs = num_urbs;
46a7df
 	tpriv->num_retired = 0;
46a7df
 	tpriv->reap_action = NORMAL;
46a7df
+	/* coverity[missing_lock] as we don't need to lock before submission */
46a7df
 	tpriv->reap_status = LIBUSB_TRANSFER_COMPLETED;
46a7df
 
46a7df
 	for (i = 0; i < num_urbs; i++) {
46a7df
46a7df
From 3c792a9b21ec07d9a3f369b9a79eec1e0f999823 Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Thu, 10 Feb 2022 10:51:11 +0100
46a7df
Subject: [PATCH 17/18] core: Silence coverity by handling long log messages in
46a7df
 one statement
46a7df
46a7df
Having two statements seems to confuse coverity. Having two checks right
46a7df
after each other doesn't give us anything, so just fold them into one so
46a7df
that the static analyzer is not getting confused.
46a7df
---
46a7df
 libusb/core.c | 13 +++++--------
46a7df
 1 file changed, 5 insertions(+), 8 deletions(-)
46a7df
46a7df
diff --git a/libusb/core.c b/libusb/core.c
46a7df
index 1643f9334..359500a9a 100644
46a7df
--- a/libusb/core.c
46a7df
+++ b/libusb/core.c
46a7df
@@ -2641,16 +2641,13 @@ static void log_v(struct libusb_context *ctx, enum libusb_log_level level,
46a7df
 		header_len = 0;
46a7df
 	}
46a7df
 
46a7df
-	text_len = vsnprintf(buf + header_len, sizeof(buf) - (size_t)header_len,
46a7df
+	text_len = vsnprintf(buf + header_len,
46a7df
+		sizeof(buf) - (size_t)header_len - (int)sizeof(USBI_LOG_LINE_END),
46a7df
 		format, args);
46a7df
-	if (text_len < 0 || text_len + header_len >= (int)sizeof(buf)) {
46a7df
+	if (text_len < 0 || text_len + header_len + (int)sizeof(USBI_LOG_LINE_END) >= (int)sizeof(buf)) {
46a7df
 		/* Truncated log output. On some platforms a -1 return value means
46a7df
-		 * that the output was truncated. */
46a7df
-		text_len = (int)sizeof(buf) - header_len;
46a7df
-	}
46a7df
-	if (header_len + text_len + (int)sizeof(USBI_LOG_LINE_END) >= (int)sizeof(buf)) {
46a7df
-		/* Need to truncate the text slightly to fit on the terminator. */
46a7df
-		text_len -= (header_len + text_len + (int)sizeof(USBI_LOG_LINE_END)) - (int)sizeof(buf);
46a7df
+		 * that the output was truncated (e.g. glibc < 2.1). */
46a7df
+		text_len = (int)sizeof(buf) - header_len - (int)sizeof(USBI_LOG_LINE_END);
46a7df
 	}
46a7df
 	strcpy(buf + header_len + text_len, USBI_LOG_LINE_END);
46a7df
 
46a7df
46a7df
From c6033e4f7f30a0ee1d872dc11ec461b812b5e4e6 Mon Sep 17 00:00:00 2001
46a7df
From: Benjamin Berg <bberg@redhat.com>
46a7df
Date: Thu, 31 Mar 2022 11:49:11 +0200
46a7df
Subject: [PATCH 18/18] linux: Avoid NULL pointer dereference warning from gcc
46a7df
46a7df
This warning is a false positive. It occurs because the HANDLE_CTX
46a7df
checks whether the passed device handle is non-NULL, returning NULL if
46a7df
it is. However, in these cases the handle is guaranteed to not be NULL
46a7df
and adding an explicit non-NULL check does not avoid the warning.
46a7df
---
46a7df
 libusb/os/linux_usbfs.c | 4 ++--
46a7df
 1 file changed, 2 insertions(+), 2 deletions(-)
46a7df
46a7df
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
46a7df
index 35cc54ab5..6e3ea49af 100644
46a7df
--- a/libusb/os/linux_usbfs.c
46a7df
+++ b/libusb/os/linux_usbfs.c
46a7df
@@ -1433,7 +1433,7 @@ static void op_close(struct libusb_device_handle *dev_handle)
46a7df
 
46a7df
 	/* fd may have already been removed by POLLERR condition in op_handle_events() */
46a7df
 	if (!hpriv->fd_removed)
46a7df
-		usbi_remove_event_source(HANDLE_CTX(dev_handle), hpriv->fd);
46a7df
+		usbi_remove_event_source(DEVICE_CTX(dev_handle->dev), hpriv->fd);
46a7df
 	if (!hpriv->fd_keep)
46a7df
 		close(hpriv->fd);
46a7df
 }
46a7df
@@ -2736,7 +2736,7 @@ static int op_handle_events(struct libusb_context *ctx,
46a7df
 			/* remove the fd from the pollfd set so that it doesn't continuously
46a7df
 			 * trigger an event, and flag that it has been removed so op_close()
46a7df
 			 * doesn't try to remove it a second time */
46a7df
-			usbi_remove_event_source(HANDLE_CTX(handle), hpriv->fd);
46a7df
+			usbi_remove_event_source(DEVICE_CTX(handle->dev), hpriv->fd);
46a7df
 			hpriv->fd_removed = 1;
46a7df
 
46a7df
 			/* device will still be marked as attached if hotplug monitor thread