CVE-2023-53641CVE-2023-53641是Linux内核中ath9k无线网卡驱动hif_usb模块存在的一个内存泄漏漏洞。该漏洞涉及ath9k_hif_usb_rx_stream()函数中remain_skb缓冲区的处理逻辑。remain_skb是在该函数中专门分配和使用的缓冲区,用于处理两个连续URB(USB Request Block)之间的逻辑链接关系。当第一个SKB中的特定数据字段指示需要缓存一个SKB时,系统会分配remain_skb,使用memcpy复制部分数据,并在下一次调用ath9k_hif_usb_rx_stream()时继续处理。然而,当设备去初始化或挂起时,URBs可能会在两次调用之间被释放,导致ath9k_hif_usb_rx_stream()函数不再被调用,从而使已分配的remain_skb发生内存泄漏。该漏洞由Linux验证中心(linuxtesting.org)使用Syzkaller工具发现。CVSS评分为5.5,属于中危级别,攻击者需要本地低权限访问即可触发此漏洞,可能导致系统可用性受到影响(系统内存逐渐耗尽)。该漏洞影响多个Linux内核稳定版本,修复补丁已合并到多个内核分支中。
该漏洞的技术原理如下:在ath9k_hif_usb_rx_stream()函数中,存在一个名为remain_skb的缓存SKB缓冲区,用于处理跨URB的数据接收场景。当USB接收URB时,如果数据被分割到两个连续的URB中,第一个URB处理后会将未完成的数据缓存到remain_skb中,等待下一个URB到达时合并处理。
问题在于remain_skb的生命周期管理:当设备进行去初始化(deinitialization)或挂起(suspend)操作时,相关的rx URBs会被释放。如果此时remain_skb仍然持有已分配但未处理完成的数据(即remain_skb非NULL),且后续ath9k_hif_usb_rx_stream()函数不再被调用,那么这块内存将永远不会被释放,造成内存泄漏。
Syzkaller模糊测试工具能够通过特定的USB设备操作序列触发此漏洞——通过反复触发设备挂起/恢复或插拔操作,导致remain_skb累积泄漏。
修复方案:引入一个显式释放remain_skb的函数,在rx URBs被释放时调用该函数来释放缓存的SKB(如果非NULL)。remain_skb为NULL的情况有两种:一是hif_dev结构体通过kzalloc分配时初始化为NULL,二是remain_skb已在下一次ath9k_hif_usb_rx_stream()调用中被处理完毕。