From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933689Ab1KJFa7 (ORCPT ); Thu, 10 Nov 2011 00:30:59 -0500 Received: from cantor2.suse.de ([195.135.220.15]:41575 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933655Ab1KJDUG (ORCPT ); Wed, 9 Nov 2011 22:20:06 -0500 X-Mailbox-Line: From gregkh@clark.kroah.org Wed Nov 9 13:27:02 2011 Message-Id: <20111109212702.121195349@clark.kroah.org> User-Agent: quilt/0.48-16.4 Date: Wed, 09 Nov 2011 13:25:40 -0800 From: Greg KH To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, Kautuk Consul , Sarah Sharp Subject: [018/262] xhci-mem.c: Check for ring->first_seg != NULL In-Reply-To: <20111109212847.GA20838@kroah.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.0-stable review patch. If anyone has any objections, please let me know. ------------------ From: Kautuk Consul commit 0e6c7f746ea99089fb3263709075c20485a479ae upstream. There are 2 situations wherein the xhci_ring* might not get freed: - When xhci_ring_alloc() -> xhci_segment_alloc() returns NULL and we goto the fail: label in xhci_ring_alloc. In this case, the ring will not get kfreed. - When the num_segs argument to xhci_ring_alloc is passed as 0 and we try to free the rung after that. ( This doesn't really happen as of now in the code but we seem to be entertaining num_segs=0 in xhci_ring_alloc ) This should be backported to kernels as old as 2.6.31. Signed-off-by: Kautuk Consul Signed-off-by: Sarah Sharp Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mem.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -112,18 +112,20 @@ void xhci_ring_free(struct xhci_hcd *xhc struct xhci_segment *seg; struct xhci_segment *first_seg; - if (!ring || !ring->first_seg) + if (!ring) return; - first_seg = ring->first_seg; - seg = first_seg->next; - xhci_dbg(xhci, "Freeing ring at %p\n", ring); - while (seg != first_seg) { - struct xhci_segment *next = seg->next; - xhci_segment_free(xhci, seg); - seg = next; + if (ring->first_seg) { + first_seg = ring->first_seg; + seg = first_seg->next; + xhci_dbg(xhci, "Freeing ring at %p\n", ring); + while (seg != first_seg) { + struct xhci_segment *next = seg->next; + xhci_segment_free(xhci, seg); + seg = next; + } + xhci_segment_free(xhci, first_seg); + ring->first_seg = NULL; } - xhci_segment_free(xhci, first_seg); - ring->first_seg = NULL; kfree(ring); }