PT-2026-90077 · Linux · Linux

CVE-2026-80947

·

Published

2026-09-11

·

Updated

2026-09-11

None

No severity ratings or metrics are available. When they are, we'll update the corresponding info on the page.
In the Linux kernel, the following vulnerability has been resolved:
wifi: rtl8xxxu: fix use-after-free from rx urb wq on stop
rtl8xxxu arms rx urb wq from the RX completion path: rtl8xxxu rx complete() hands the URB to rtl8xxxu queue rx urb(), which queues it on rx urb pending list and, once the list grows past RTL8XXXU RX URB PENDING WATER, schedules rx urb wq. The worker rtl8xxxu rx urb work() drains rx urb pending list, recovers priv through container of, and resubmits each URB through rtl8xxxu submit rx urb(), which anchors it on rx anchor and dereferences priv->udev.
rtl8xxxu stop() cancels the sibling work items (c2hcmd work, ra watchdog, update beacon work) but never cancels rx urb wq, so a worker armed during the last burst of RX traffic can run rtl8xxxu rx urb work() after rtl8xxxu disconnect() has called ieee80211 free hw(), which frees priv, producing a use-after-free. The window opens under active RX traffic (pending count above the watermark) followed by a disconnect.
There are two teardown races to close:
  • rtl8xxxu queue rx urb() decided whether to enqueue under rx urb lock but called schedule work() after dropping the lock. A completion that observed shutdown == false and released the lock could then call schedule work() after rtl8xxxu stop() had set shutdown and cancel work sync() had already returned, arming the worker to run after the teardown. Move schedule work() under the same !shutdown branch so the arming decision is atomic with the shutdown check.
  • rtl8xxxu rx urb work() anchors every URB it drained back onto rx anchor through rtl8xxxu submit rx urb(). A worker still running when usb kill anchored urbs(&priv->rx anchor) returned would submit a URB that escaped the kill. In rtl8xxxu stop(), call cancel work sync(&priv->rx urb wq) before the kill so the worker is drained first.
After priv->shutdown is set under rx urb lock, completions can no longer queue rx urb wq. cancel work sync() then drains the last queued or running worker, and the following usb kill anchored urbs() kills the URBs it may have submitted.
rtl8xxxu disconnect() is covered because ieee80211 unregister hw() guarantees .stop() runs for a live interface before ieee80211 free hw() frees priv. The probe error path needs no cancel: rx urb wq is INIT WORK()'d there but cannot have been scheduled, since no URB is submitted before ieee80211 register hw() succeeds.
This bug was found by static analysis.
Found an issue in the description? Have something to add? Feel free to write us 👾

Related Identifiers

CVE-2026-80947

Affected Products

Linux