CVE-2022-50483CVE-2022-50483是Linux内核中ENETC(Enhanced Network Controller)网络驱动的一个缓冲区泄漏漏洞。该漏洞位于enetc_clean_rx_ring_xdp()函数中,与XDP(eXpress Data Path)的重定向操作相关。在XDP重定向失败时,由于enetc_flip_rx_buff()在半页翻转过程中将rx_swbd->page指针置空,导致错误处理路径enetc_xdp_free()无法正确释放页面引用,最终造成页面缓冲区泄漏。
该漏洞的根本原因是页面引用计数管理不当。在调用xdp_do_redirect()之前,每个软件BD(Buffer Descriptor)的页面引用计数可能为1或2。当xdp_do_redirect()返回错误时,代码调用enetc_xdp_free(),但由于rx_swbd->page已被置空,无法正确处理页面引用,导致引用计数为2的页面被泄漏。随着时间推移,系统会持续分配新页面并不断泄漏,最终可能耗尽内存资源,导致系统不稳定或拒绝服务。
该漏洞的CVSS评分为5.5,属于中危级别。攻击者需要本地低权限访问权限,无需用户交互。虽然机密性和完整性影响较低,但高可用性影响意味着系统可能因内存耗尽而变得不可用。
漏洞的核心技术细节在于ENETC驱动中RX环描述符的页面引用计数管理。ENETC驱动使用半页(half-page)翻转技术来高效管理RX缓冲区。在正常路径中,enetc_flip_rx_buff()调用enetc_page_reusable()检查页面引用计数是否为1,如果是则将当前rx_swbd的页面指针转移到对侧的rx_swbd,并通过enetc_reuse_page()将引用计数增加到2。
问题出在以下场景:当xdp_do_redirect()触发devmap/cpumap批量队列刷新,且消费者释放了缓冲区时,页面引用计数可能变为0。然而,enetc_flip_rx_buff()在xdp_do_redirect()调用之前执行,并会在两个分支中都执行rx_swbd->page = NULL操作。当xdp_do_redirect()返回错误时,enetc_xdp_free()被调用但无法处理已被置空的页面指针。
具体泄漏路径为:1) 页面引用计数初始为1;2) enetc_flip_rx_buff()判断页面可重用,将指针转移到对侧rx_swbd,引用计数变为2;3) xdp_do_redirect()返回错误;4) 调用no-op的enetc_xdp_free(),引用计数仍为2;5) 第二次翻转时,引用计数为2的页面被判断为不可重用,导致泄漏。
修复方案是将翻转操作移至重定向成功路径,并使用enetc_xdp_drop()替代enetc_xdp_free()来回收缓冲区,避免页面泄漏。