patch "xhci: Fix NULL pointer dereference when cleaning up streams for" added to usb-linus
Subsystems (3)
This is a note to let you know that I've just added the patch titled
xhci: Fix NULL pointer dereference when cleaning up streams for
to my usb git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
in the usb-linus branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the next -rc kernel release.
If you have any questions about this process, please let me know.
Quoted 1 line
From
4b895868bb2da60a386a17cde3bf9ecbc70c79f4Mon Sep 17 00:00:00 2001
From: Mathias Nyman <[email protected]>
Date: Thu, 20 Jul 2017 14:48:26 +0300
Subject: xhci: Fix NULL pointer dereference when cleaning up streams for
removed host
This off by one in stream_id indexing caused NULL pointer dereference and soft lockup on machines with USB attached SCSI devices connected to a hotpluggable xhci controller.
The code that cleans up pending URBs for dead hosts tried to dereference a stream ring at the invalid stream_id 0. ep->stream_info->stream_rings[0] doesn't point to a ring.
Start looping stream_id from 1 like in all the other places in the driver, and check that the ring exists before trying to kill URBs on it.
--- drivers/usb/host/xhci-ring.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/usb/host/xhci-ring.c +7 -4
@@ -864,13 +864,16 @@ static void xhci_kill_endpoint_urbs(struct xhci_hcd *xhci, (ep->ep_state & EP_GETTING_NO_STREAMS)) {int stream_id; -for (stream_id =0 ; stream_id < ep->stream_info->num_streams; +for (stream_id =1 ; stream_id < ep->stream_info->num_streams; stream_id++) { + ring = ep->stream_info->stream_rings[stream_id]; +if (!ring) +continue ; +xhci_dbg_trace (xhci, trace_xhci_dbg_cancel_urb,"Killing URBs for slot ID %u, ep index %u, stream %u" , - slot_id, ep_index, stream_id +1 ); -xhci_kill_ring_urbs (xhci, - ep->stream_info->stream_rings[stream_id]); + slot_id, ep_index, stream_id); +xhci_kill_ring_urbs (xhci, ring); } } else { ring = ep->ring;
Signature · 1 line
2.13.3