From: Cheng Yongkang <teel4res@gmail.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Mathias Nyman <mathias.nyman@intel.com>
Cc: Alan Stern <stern@rowland.harvard.edu>,
linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [BUG] usb: failed altsetting restore leaves xHCI ep with a NULL ring
Date: Sun, 15 Nov 2026 08:37:16 -0800 [thread overview]
Message-ID: <20261115163716.226763-1-teel4res@gmail.com> (raw)
Hi Greg, Mathias,
This one is from reading the code only; I could not reproduce it. It
needs SET_INTERFACE to fail and then the restore of the old altsetting
to fail too, on xHCI, so it is very unlikely in practice.
I know the kerneldoc of usb_set_interface() says that after a failure
the original altsetting may be disabled and drivers cannot rely on any
altsetting being in effect. My concern is only that a later usbfs
ioctl can still reach the HCD with that endpoint and oops.
The sequence, as I read it in next-20261113:
1. usb_set_interface() calls usb_disable_interface(dev, iface, false)
and then usb_hcd_alloc_bandwidth() for the new altsetting. On xHCI,
xhci_check_bandwidth() frees the rings of the old endpoints that
are not reused. xhci_drop_endpoint() does not clear their hcpriv.
2. SET_INTERFACE fails, and the restore call
usb_hcd_alloc_bandwidth(dev, NULL, alt, iface->cur_altsetting)
fails too, for example on a ring allocation failure. Its result is
ignored, and cur_altsetting still points at the old altsetting.
3. USBDEVFS_RESETEP on a bulk or interrupt endpoint of that old
altsetting passes findintfep() and checkintf(). usb_reset_endpoint()
still finds the endpoint, because usb_disable_endpoint() with
reset_hardware=false keeps dev->ep_in/out[], and nothing checks
ep->enabled.
4. xhci_endpoint_reset() sees a non-NULL hcpriv, passes its other
checks, and reaches list_empty(&ep->ring->td_list) with a NULL
ring.
Either side could avoid it: usb_set_interface() could check the
restore result and disable the interface with reset_hardware=true,
or xhci_endpoint_reset() could return early when ep->ring is NULL.
I have a draft of the first, but it is only tested on the normal
altsetting paths, not on this failure. Please tell me if you think it
is worth fixing and where.
Thanks,
Cheng Yongkang
reply other threads:[~2026-11-15 16:37 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261115163716.226763-1-teel4res@gmail.com \
--to=teel4res@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mathias.nyman@intel.com \
--cc=stern@rowland.harvard.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox