CVE-2022-50481CVE-2022-50481是Linux内核CXL(Compute Express Link)子系统中存在的一个空指针解引用漏洞。该漏洞位于cxl_guest_init_afu()和cxl_guest_init_adapter()函数中,涉及CXL Guest驱动在初始化AFU(Accelerator Functional Unit)和Adapter时的设备注册流程。当device_register()调用失败时,设备并未成功添加到系统中,但原有的错误处理路径中调用了device_unregister()来清理资源。由于device_unregister()内部会尝试移除一个并未被添加的设备,这会导致对未初始化或空指针的访问,从而触发空指针解引用错误,可能引发内核崩溃(Kernel Panic)或系统拒绝服务。该漏洞的CVSS评分为5.5,属于中等严重等级,攻击者需要本地低权限访问权限,无需用户交互即可触发,但仅影响系统的可用性(Availability),不涉及机密性和完整性的破坏。此漏洞主要影响在虚拟化环境中使用CXL Guest驱动的Linux系统,修复方案是将device_unregister()拆分为device_del()和put_device()两个调用,在设备注册失败时仅释放引用而非尝试移除设备,从而避免空指针解引用的发生。
该漏洞的技术根源在于Linux内核设备模型中设备注册和注销的不当使用模式。在Linux设备模型中,device_register()函数用于将设备注册到系统中,使其对其他子系统可见。该函数内部调用device_add()来完成实际的注册操作。当device_register()成功执行后,设备被添加到内核的设备层次结构中,此时才能安全地调用device_unregister()来移除设备。
在CXL Guest驱动的cxl_guest_init_afu()和cxl_guest_init_adapter()函数中,当device_register()调用失败时,设备并未被成功添加到设备层次结构中。然而,原始的错误处理代码仍然调用device_unregister(),该函数会执行device_del()操作。device_del()会尝试从设备层次结构中移除设备并执行各种清理操作,但由于设备从未被正确添加,这会导致对NULL指针或无效内存地址的解引用访问,从而触发内核oops或panic。
修复方案遵循了Linux内核中device_register()函数注释的建议:在注册失败的错误路径中,应使用put_device()来释放对设备的引用,而不是调用device_unregister()。具体实现是将错误处理路径中的device_unregister()拆分为device_del()和put_device()两个独立的调用,并在device_register()失败时仅调用put_device()来释放引用计数。
利用方面,由于该漏洞需要本地低权限访问权限(PR:L),攻击者需要能够在目标系统上执行代码。触发条件相对简单——只需要加载CXL Guest驱动并触发AFU或Adapter的初始化过程,使其在特定条件下导致device_register()失败即可。成功利用该漏洞将导致系统崩溃或拒绝服务状态。