CVE-2025-39948CVE-2025-39948是Linux内核中Intel ice网络驱动存在的一个内存泄漏漏洞。该漏洞位于ice_put_rx_mbuf()函数中,该函数负责处理多缓冲区帧中每个缓冲区的回收操作。当硬件提交大小为0的描述符时,现有的迭代逻辑会跳过这些描述符,导致它们未被计为fragment,从而在ice_put_rx_mbuf()的迭代中也不会被处理,最终造成ice_put_rx_buf()不会被调用,使得页面既不会被重用也不会被释放。
此漏洞仅影响多缓冲区帧(multi-buffer frames),单缓冲区帧不受影响。触发条件通常与使用9K MTU的巨型帧(jumbo frames)有关,硬件在某些情况下会定期提交大小为0的描述符。由于泄漏的页面不会增加next_to_alloc计数器,而ice_reuse_rx_page()函数假定next_to_alloc始终指向具有NULL页面的缓冲区,因此会错误地在next_to_alloc缓冲区上回收页面,导致旧页面丢失跟踪。该漏洞的CVSS评分为5.5,属于中危级别,需要本地低权限即可触发,但对系统可用性影响较高,可能导致内存耗尽。
该漏洞的根本原因在于ice驱动中多缓冲区帧处理逻辑的缺陷。具体技术细节如下:
1. ice_put_rx_mbuf()函数通过迭代从first_desc到fragment总数的缓冲区来处理多缓冲区帧的回收。该fragment数量在XDP程序执行前被缓存。
2. 当硬件提交大小为0的描述符时,ice_add_xdp_frag()会跳过这些描述符,不将其计为fragment。由于fragment计数不正确,ice_put_rx_mbuf()的迭代循环不会遍历到这些被跳过的缓冲区,导致ice_put_rx_buf()永远不会被调用。
3. 由于ice_put_rx_buf()未被调用,页面既不会被重用也不会被释放,next_to_alloc计数器也不会递增。这导致ring中留下陈旧的页面引用。
4. ice_reuse_rx_page()函数假设next_to_alloc已正确递增且始终指向NULL页面的缓冲区,但该函数不进行任何检查,因此会在next_to_alloc缓冲区上直接回收页面,覆盖原有页面引用,造成页面泄漏。
5. 修复方案借鉴了i40e驱动中类似函数的逻辑,改为迭代从first_desc到next_to_clean的所有缓冲区,确保所有缓冲区都被正确处理。同时调整了pagecnt_bias的更新逻辑,只对第一个描述符和XDP程序执行后仍存在的fragment进行更新。