CVE-2022-50476CVE-2022-50476是Linux内核ntb_netdev驱动中的一个漏洞,主要影响使用AMD PTDMA DMA引擎的系统。该漏洞源于ntb_netdev的TX/RX回调处理函数(ntb_netdev_tx_handler()和ntb_netdev_rx_handler())在中断上下文中被调用时,使用了非中断安全的dev_kfree_skb()函数来释放skb(socket buffer)。这些回调函数通过DMA框架在DMA操作完成时被调用,可能运行在硬中断上下文中。在Intel IOAT DMA引擎上,该驱动使用tasklets而非硬中断处理程序,因此未表现出明显问题。但在AMD PTDMA DMA驱动上,由于使用硬中断处理程序,调用非中断安全的dev_kfree_skb()会触发内核WARNING消息,该消息由skb_release_head_state()发出,原因是in_hardirq()返回true。除了用户可见的内核警告外,该漏洞还会导致ntb_netdev接口上的TCP/IP性能严重下降,约为预期性能的十分之一。修复后使用dev_kfree_skb_any()函数,该函数在中断上下文中安全,kernel警告停止,性能恢复到预期水平,在AMD Milan服务器上使用iperf测试可达到约20 Gb/s。该漏洞CVSS评分为5.5,属于中危级别,本地低权限攻击者即可触发,可能导致系统可用性受到影响。
该漏洞的技术原理在于Linux内核网络子系统中skb释放函数的上下文安全性问题。dev_kfree_skb()是用于释放skb的标准函数,但它不是中断安全的,不能在硬中断上下文中调用。而dev_kfree_skb_any()是一个可以在任何上下文中安全调用的版本。
在ntb_netdev驱动中,当DMA操作完成时,会触发回调函数ntb_netdev_tx_handler()和ntb_netdev_rx_handler()。这些回调函数在DMA框架的硬中断处理程序中被调用。当使用AMD PTDMA DMA驱动时,回调直接运行在硬中断上下文中。此时调用非中断安全的dev_kfree_skb()会导致两个问题:
1. 内核会检测到在硬中断上下文中执行非安全操作,从skb_release_head_state()发出WARNING消息。
2. 由于中断上下文中的不当处理,skb释放可能不正确,导致TCP/IP性能大幅下降(约10倍性能损失)。
利用方式:本地低权限用户只需在受影响系统上正常使用ntb_netdev接口(如通过ntb传输网络流量),即可触发该漏洞。攻击者可以通过持续的网络流量使DMA操作频繁完成,反复触发中断上下文中的错误代码路径,导致系统日志被WARNING消息淹没,并使网络性能严重下降,影响系统可用性。
修复方法是将dev_kfree_skb()替换为dev_kfree_skb_any(),后者会根据当前上下文自动选择合适的释放方式,确保在硬中断上下文中也能安全执行。