Patchwork [3.5.y.z,extended,stable] Patch "xhci: fix null-pointer dereference when destroying" has been added to staging queue

mail settings
Submitter Herton Ronaldo Krzesinski
Date Jan. 7, 2013, 8:33 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/210134/
State New
Headers show


Herton Ronaldo Krzesinski - Jan. 7, 2013, 8:33 p.m.
This is a note to let you know that I have just added a patch titled

    xhci: fix null-pointer dereference when destroying

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see



From 3f18ab73cef1a8756eeee55507ed1a0610157670 Mon Sep 17 00:00:00 2001
From: Julius Werner <>
Date: Thu, 1 Nov 2012 12:47:59 -0700
Subject: [PATCH] xhci: fix null-pointer dereference when destroying
 half-built segment rings

commit 68e5254adb88bede68285f11fb442a4d34fb550c upstream.

xhci_alloc_segments_for_ring() builds a list of xhci_segments and links
the tail to head at the end (forming a ring). When it bails out for OOM
reasons half-way through, it tries to destroy its half-built list with
xhci_free_segments_for_ring(), even though it is not a ring yet. This
causes a null-pointer dereference upon hitting the last element.

Furthermore, one of its callers (xhci_ring_alloc()) mistakenly believes
the output parameters to be valid upon this kind of OOM failure, and
calls xhci_ring_free() on them. Since the (incomplete) list/ring should
already be destroyed in that case, this would lead to a use after free.

This patch fixes those issues by having xhci_alloc_segments_for_ring()
destroy its half-built, non-circular list manually and destroying the
invalid struct xhci_ring in xhci_ring_alloc() with a plain kfree().

This patch should be backported to kernels as old as 2.6.31, that
contains the commit 0ebbab37422315a5d0cb29792271085bafdf38c0 "USB: xhci:
Ring allocation and initialization."

A separate patch will need to be developed for kernels older than 3.4,
since the ring allocation code was refactored in that kernel.

Signed-off-by: Julius Werner <>
Signed-off-by: Sarah Sharp <>
Signed-off-by: Herton Ronaldo Krzesinski <>
 drivers/usb/host/xhci-mem.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)



diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 487bc08..fb51c70 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -205,7 +205,12 @@  static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,

 		next = xhci_segment_alloc(xhci, cycle_state, flags);
 		if (!next) {
-			xhci_free_segments_for_ring(xhci, *first);
+			prev = *first;
+			while (prev) {
+				next = prev->next;
+				xhci_segment_free(xhci, prev);
+				prev = next;
+			}
 			return -ENOMEM;
 		xhci_link_segments(xhci, prev, next, type);
@@ -258,7 +263,7 @@  static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
 	return ring;

-	xhci_ring_free(xhci, ring);
+	kfree(ring);
 	return NULL;