CVE-2022-50520CVE-2022-50520是Linux内核中drm/radeon子模块的一个引用计数泄漏漏洞,位于`radeon_atrm_get_bios()`函数中。该漏洞源于`pci_get_class()`函数的调用方式存在缺陷:根据内核文档说明,`pci_get_class()`会返回一个增加了引用计数的pci_device,并且当输入参数@from不为NULL时会减少该参数的引用计数。在`radeon_atrm_get_bios()`函数中,如果循环在`pdev`不为NULL的情况下被中断(即找到了匹配的PCI设备),代码缺少对`pci_dev_put()`的调用来正确释放增加的引用计数,从而导致PCI设备的引用计数泄漏。
虽然该漏洞本身不会直接导致权限提升或数据泄露,但由于引用计数持续泄漏,在长时间运行的系统中,特别是在频繁触发相关代码路径的场景下(如反复加载/卸载Radeon显卡驱动或热插拔显卡),可能导致内核中PCI设备结构体的引用计数无法归零,进而引发资源耗尽或内核不稳定等问题,严重时可导致系统崩溃或内核panic。该漏洞的CVSS评分为5.5分,属于中危级别,主要影响系统的可用性。
该漏洞由Linux内核社区的安全研究人员发现并修复,修复补丁已合入多个稳定内核版本,包括5.10.x、5.15.x、5.19.x等多个长期支持(LTS)分支。
该漏洞的技术原理如下:
1. **漏洞触发点**:`radeon_atrm_get_bios()`函数位于`drivers/gpu/drm/radeon/radeon_atrm.c`文件中,负责通过遍历PCI设备获取Radeon显卡的BIOS信息。
2. **核心问题**:函数使用`pci_get_class()`遍历系统中所有PCI设备以查找匹配的显卡设备。`pci_get_class()`的语义是:每次调用都会返回一个新的pci_device结构体指针,该结构体的引用计数已被增加。当遍历循环找到一个匹配设备并通过`break`跳出时,代码没有调用`pci_dev_put()`来释放该设备的引用计数。
3. **泄漏机制**:在内核中,每个PCI设备结构体(`struct pci_dev`)都有一个引用计数(`kref`),用于跟踪有多少地方正在使用该设备。当引用计数不为零时,设备结构体不会被释放。缺少`pci_dev_put()`调用意味着每次执行该代码路径都会使受影响设备的引用计数永久增加1。
4. **利用方式**:虽然这不是一个传统意义上的可利用漏洞,但攻击者可以通过以下方式触发:
- 在具有Radeon显卡的系统上,通过udev规则或modprobe配置反复触发显卡驱动的初始化流程
- 通过编写内核模块或利用其他漏洞调用`radeon_atrm_get_bios()`
- 长时间运行后,引用计数累积导致系统资源耗尽
5. **修复方案**:在内核补丁中,在`break`跳出循环后添加了`pci_dev_put(pdev)`调用,确保正确释放PCI设备的引用计数,防止泄漏。
6. **影响评估**:由于该漏洞需要本地权限(PR:L)才能触发,且不涉及机密性或完整性破坏(仅影响可用性),攻击者最多只能通过反复触发该路径导致系统不稳定或内核panic。