CVE-2025-39954CVE-2025-39954是Linux内核中sunxi-ng时钟驱动mp子模块的一个除零漏洞。该漏洞位于时钟子系统的.recalc_rate读回函数中。当引入双分频器(dual-divider)时钟支持时,开发者在重计算速率的函数中遗漏了P分频器偏移量(divider offset)的处理。这导致在调用clk_get_rate()等接口读取时钟频率时,函数返回错误的时钟速率值,甚至返回零值。由于P分频器的值可能为1,在计算过程中会触发除零异常,从而导致内核崩溃或系统不可用。
该漏洞的CVSS评分为5.5,属于中危级别。攻击者需要本地低权限访问即可触发此漏洞,无需用户交互。漏洞的主要影响是系统可用性,机密性和完整性不受影响。受影响的Linux内核版本涉及多个稳定分支,具体版本信息可参考kernel.org上的修复提交。由于该漏洞位于时钟驱动层面,影响所有使用Allwinner(sunxi)系列SoC的平台,包括但不限于各种ARM开发板和嵌入式设备。修复方案已在主线和稳定内核中通过提交25fbbaf515acd13399589bd5ee6de5f35740cef2和40108f69c372af3aea73e7829d6849a44638d662发布。
该漏洞的技术根源在于clk: sunxi-ng: mp驱动中双分频器时钟的速率重计算逻辑不完整。在Allwinner SoC的硬件设计中,时钟树包含多个分频器级联结构,其中P分频器(pre-divider)是第一级分频器,M分频器是第二级分频器。当引入dual-divider支持时,.recalc_rate回调函数被修改以处理两级分频器,但开发者遗漏了将P分频器的偏移量纳入最终速率计算公式。
具体而言,正确的速率计算公式应为:rate = parent_rate / (p_div + p_offset) / (m_div + m_offset)。然而,由于遗漏了p_offset,当P分频器的值为1时,计算结果变为parent_rate / 1 / m_div = parent_rate / m_div,看似正常;但当硬件实际配置中P分频器的有效值为0(即寄存器值为0,但实际分频比为1)时,公式退化为parent_rate / 0 / m_div,触发内核除零错误(divide-by-zero),导致oops或panic。
利用方式方面,攻击者需要本地访问权限(PR:L),可以通过以下方式触发:1)编写一个简单的内核模块或用户空间程序(通过/dev/clk等接口),调用clk_get_rate()读取受影响的时钟频率;2)当特定时钟的P分频器寄存器值为0时,内核在重计算速率时触发除零;3)导致内核oops或系统崩溃。该漏洞不需要特殊权限,普通用户即可触发系统拒绝服务。