Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755250Ab0LHAee (ORCPT ); Tue, 7 Dec 2010 19:34:34 -0500 Received: from kroah.org ([198.145.64.141]:54785 "EHLO coco.kroah.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755078Ab0LHAec (ORCPT ); Tue, 7 Dec 2010 19:34:32 -0500 X-Mailbox-Line: From gregkh@clark.site Tue Dec 7 16:06:41 2010 Message-Id: <20101208000641.423978067@clark.site> User-Agent: quilt/0.48-11.2 Date: Tue, 07 Dec 2010 16:04:18 -0800 From: Greg KH To: linux-kernel@vger.kernel.org, stable@kernel.org Cc: stable-review@kernel.org, torvalds@linux-foundation.org, akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, Alan Stern , David Brownell Subject: [19/44] USB: EHCI: fix obscure race in ehci_endpoint_disable In-Reply-To: <20101208003205.GA4286@kroah.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2336 Lines: 67 2.6.27-stable review patch. If anyone has any objections, please let us know. ------------------ From: Alan Stern commit 02e2c51ba3e80acde600721ea784c3ef84da5ea1 upstream. This patch (as1435) fixes an obscure and unlikely race in ehci-hcd. When an async URB is unlinked, the corresponding QH is removed from the async list. If the QH's endpoint is then disabled while the URB is being given back, ehci_endpoint_disable() won't find the QH on the async list, causing it to believe that the QH has been lost. This will lead to a memory leak at best and quite possibly to an oops. The solution is to trust usbcore not to lose track of endpoints. If the QH isn't on the async list then it doesn't need to be taken off the list, but the driver should still wait for the QH to become IDLE before disabling it. In theory this fixes Bugzilla #20182. In fact the race is so rare that it's not possible to tell whether the bug is still present. However, adding delays and making other changes to force the race seems to show that the patch works. Signed-off-by: Alan Stern Reported-by: Stefan Richter CC: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -954,10 +954,11 @@ rescan: tmp && tmp != qh; tmp = tmp->qh_next.qh) continue; - /* periodic qh self-unlinks on empty */ - if (!tmp) - goto nogood; - unlink_async (ehci, qh); + /* periodic qh self-unlinks on empty, and a COMPLETING qh + * may already be unlinked. + */ + if (tmp) + unlink_async(ehci, qh); /* FALL THROUGH */ case QH_STATE_UNLINK: /* wait for hw to finish? */ case QH_STATE_UNLINK_WAIT: @@ -972,7 +973,6 @@ idle_timeout: } /* else FALL THROUGH */ default: -nogood: /* caller was supposed to have unlinked any requests; * that's not our job. just leak this memory. */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/