Commit 04d21f72 authored by Mathias Nyman's avatar Mathias Nyman Committed by Greg Kroah-Hartman

xhci: prevent a theoretical endless loop while preparing rings.

xhci driver links together segments in a ring buffer by turning the last
TRB of a segment into a link TRB, pointing to the beginning of
the next segment.

If the first TRB of every segment for some unknown reason is a link TRB
pointing to the next segment, then prepare_ring() loops indefinitely.
This isn't something the xhci driver would do.
xHC hardware has access to these rings, it sholdn't be writing link
TRBs either, but with broken xHC hardware this could in theory be
possible.
Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20210129130044.206855-10-mathias.nyman@linux.intel.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c089cada
......@@ -2952,6 +2952,7 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
u32 ep_state, unsigned int num_trbs, gfp_t mem_flags)
{
unsigned int num_trbs_needed;
unsigned int link_trb_count = 0;
/* Make sure the endpoint has been added to xHC schedule */
switch (ep_state) {
......@@ -3023,6 +3024,12 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
ep_ring->enq_seg = ep_ring->enq_seg->next;
ep_ring->enqueue = ep_ring->enq_seg->trbs;
/* prevent infinite loop if all first trbs are link trbs */
if (link_trb_count++ > ep_ring->num_segs) {
xhci_warn(xhci, "Ring is an endless link TRB loop\n");
return -EINVAL;
}
}
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment