Skip to contentSkip to conversation

Patch "USB: dummy-hcd: fix infinite-loop resubmission bug" has been added to the 4.13-stable tree

PATCH [email protected] 1 participant 1 message Oct 9, 2017

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

USB: dummy-hcd: fix infinite-loop resubmission bug

to the 4.13-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
usb-dummy-hcd-fix-infinite-loop-resubmission-bug.patch
and it can be found in the queue-4.13 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 0173a68bfb0ad1c72a6ee39cc485aa2c97540b98 Mon Sep 17 00:00:00 2001

From: Alan Stern <[email protected]>
Date: Tue, 26 Sep 2017 15:15:40 -0400
Subject: USB: dummy-hcd: fix infinite-loop resubmission bug

From: Alan Stern <[email protected]>

commit 0173a68bfb0ad1c72a6ee39cc485aa2c97540b98 upstream.

The dummy-hcd HCD/UDC emulator tries not to do too much work during each timer interrupt. But it doesn't try very hard; currently all it does is limit the total amount of bulk data transferred. Other transfer types aren't limited, and URBs that transfer no data (because of an error, perhaps) don't count toward the limit, even though on a real USB bus they would consume at least a minimum overhead.

This means it's possible to get the driver stuck in an infinite loop, for example, if the host class driver resubmits an URB every time it completes (which is common for interrupt URBs). Each time the URB is resubmitted it gets added to the end of the pending-URBs list, and dummy-hcd doesn't stop until that list is empty. Andrey Konovalov was able to trigger this failure mode using the syzkaller fuzzer.

This patch fixes the infinite-loop problem by restricting the URBs handled during each timer interrupt to those that were already on the pending list when the interrupt routine started. Newly added URBs won't be processed until the next timer interrupt. The problem of properly accounting for non-bulk bandwidth (as well as packet and transaction overhead) is not addressed here.

---
 drivers/usb/gadget/udc/dummy_hcd.c |    9 +++++++++
 1 file changed, 9 insertions(+)
drivers/usb/gadget/udc/dummy_hcd.c +9 -0
@@ -237,6 +237,8 @@ struct dummy_hcd {
 
 	struct usb_device		*udev;
 	struct list_head		urbp_list;
+	struct urbp			*next_frame_urbp;
+
 	u32				stream_en_ep;
 	u8				num_stream[30 / 2];
 
@@ -1251,6 +1253,8 @@ static int dummy_urb_enqueue(
 
 	list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list);
 	urb->hcpriv = urbp;
+	if (!dum_hcd->next_frame_urbp)
+		dum_hcd->next_frame_urbp = urbp;
 	if (usb_pipetype(urb->pipe) == PIPE_CONTROL)
 		urb->error_count = 1;		/* mark as a new urb */
 
@@ -1767,6 +1771,7 @@ static void dummy_timer(unsigned long _d
 		spin_unlock_irqrestore(&dum->lock, flags);
 		return;
 	}
+	dum_hcd->next_frame_urbp = NULL;
 
 	for (i = 0; i < DUMMY_ENDPOINTS; i++) {
 		if (!ep_info[i].name)
@@ -1783,6 +1788,10 @@ restart:
 		int			type;
 		int			status = -EINPROGRESS;
 
+		/* stop when we reach URBs queued after the timer interrupt */
+		if (urbp == dum_hcd->next_frame_urbp)
+			break;
+
 		urb = urbp->urb;
 		if (urb->unlinked)
 			goto return_urb;

Patches currently in stable-queue which might be from [email protected] are

queue-4.13/usb-storage-fix-bogus-hardware-error-messages-for-ata-pass-thru-devices.patch queue-4.13/usb-devio-prevent-integer-overflow-in-proc_do_submiturb.patch queue-4.13/usb-dummy-hcd-fix-infinite-loop-resubmission-bug.patch queue-4.13/usb-storage-unusual_devs-entry-to-fix-write-access-regression-for-seagate-external-drives.patch queue-4.13/usb-gadgetfs-fix-copy_to_user-while-holding-spinlock.patch queue-4.13/usb-devio-don-t-corrupt-user-memory.patch queue-4.13/usb-gadgetfs-fix-crash-caused-by-inadequate-synchronization.patch queue-4.13/usb-dummy-hcd-fix-connection-failures-wrong-speed.patch queue-4.13/usb-dummy-hcd-fix-erroneous-synchronization-change.patch