Blame SOURCES/1067.patch

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