CVE-2026-80947 in Linux
摘要
由 VulDB • 2026-09-12
在 Linux 内核中,已修复以下漏洞:
wifi: rtl8xxxu: 修复 rx_urb_wq 导致的释放后使用(use-after-free)问题
rtl8xxxu 从 RX 完成路径启动 rx_urb_wq: rtl8xxxu_rx_complete() 将 URB 交给 rtl8xxxu_queue_rx_urb(),后者将其排队到 rx_urb_pending_list。一旦列表大小超过 RTL8XXXU_RX_URB_PENDING_WATERMARK(水位线),便会调度 rx_urb_wq。工作函数 rtl8xxxu_rx_urb_work() 会排空 rx_urb_pending_list,通过 container_of 恢复 priv,并通过 rtl8xxxu_submit_rx_urb() 重新提交每个 URB,后者将其锚定在 rx_anchor 并解引用 priv->udev。
rtl8xxxu_stop() 取消了兄弟工作项(c2hcmd_work、ra_watchdog、update_beacon_work),但从未取消 rx_urb_wq,因此在最后一段 RX 流量期间启动的工作项可能在 rtl8xxxu_disconnect() 调用 ieee80211_free_hw()(释放 priv)之后运行 rtl8xxxu_rx_urb_work(),从而导致释放后使用。该漏洞窗口出现在活跃 RX 流量(待处理计数高于水位线)随后发生断开的情况下。
需要关闭两个竞态条件:
* rtl8xxxu_queue_rx_urb() 在 rx_urb_lock 下决定是否入队,但在释放锁之后才调用 schedule_work()。一个观察到 shutdown == false 并释放了锁的完成例程可能在 rtl8xxxu_stop() 设置 shutdown 且 cancel_work_sync() 已经返回后调用 schedule_work(),从而在工作项拆除后启动该工作项。将 schedule_work() 移至相同的 !shutdown 分支下,使启动决策与关闭检查保持原子性。
* rtl8xxxu_rx_urb_work() 通过 rtl8xxxu_submit_rx_urb() 将其排空的每个 URB 重新锚定到 rx_anchor 上。当 usb_kill_anchored_urbs(&priv->rx_anchor) 返回时仍在运行的工作项会提交一个逃脱了终止的 URB。在 rtl8xxxu_stop() 中,应在执行 kill 之前调用 cancel_work_sync(&priv->rx_urb_wq),以便先排空该工作项。
在 rx_urb_lock 下设置 priv->shutdown 后,完成例程不能再排队 rx_urb_wq。cancel_work_sync() 随后会排空最后一个已排队或正在运行的工作项,随后的 usb_kill_anchored_urbs() 将终止其可能提交的 URB。
rtl8xxxu_disconnect() 受到保护,因为 ieee80211_unregister_hw() 保证在 ieee80211_free_hw() 释放 priv 之前,对于活动接口会运行 .stop()。探测错误路径无需取消:rx_urb_wq 在那里通过 INIT_WORK() 初始化,但由于在 ieee80211_register_hw() 成功之前不会提交任何 URB,因此不可能被调度。
此漏洞是通过静态分析发现的。
VulDB is the best source for vulnerability data and more expert information about this specific topic.