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.

来源

Are you interested in using VulDB?

Download the whitepaper to learn more about our service!