CVE-2022-50538CVE-2022-50538是Linux内核VME(VersaModule Eurocard)子系统中的一个中等严重性漏洞。该漏洞位于内核驱动的fake_init()函数中,主要问题是__root_device_register()函数调用可能失败,但其返回值未被正确检查和处理。当__root_device_register()返回失败时,由于没有捕获该错误,可能导致在模块退出时无法正确注销vme_root设备,从而触发系统崩溃。
具体表现为:系统在调用__x64_sys_delete_module系统调用卸载模块时,会触发通用保护故障(general protection fault),并伴随KASAN检测到的空指针解引用(null-ptr-deref)错误,访问地址范围为[0x0000000000000460-0x0000000000000467]。崩溃发生在root_device_unregister函数中,调用链为__x64_sys_delete_module -> do_syscall_64 -> entry_SYSCALL_64_after_hwframe。
该漏洞的CVSS 3.1评分为5.5分,属于中等严重等级。攻击者需要本地低权限访问即可触发此漏洞,无需用户交互。虽然机密性影响较低,但可用性影响为高,可能导致系统拒绝服务(内核崩溃)。该漏洞已在多个Linux内核稳定版本中通过补丁修复,修复方案是在__root_device_register()失败时返回错误。
该漏洞的根本原因在于Linux内核VME子系统驱动中fake_init()函数的错误处理逻辑缺陷。在fake_init()函数初始化过程中,调用了__root_device_register()来注册根设备,但该函数调用可能因内存不足或其他原因返回失败(返回ERR_PTR编码的错误指针或NULL)。然而,原代码忽略了这一返回值,没有进行错误检查。
当__root_device_register()失败时,vme_root变量可能未被正确初始化为有效的设备结构,但模块的退出代码(exit函数)仍然会尝试调用root_device_unregister()来注销该设备。由于设备结构未正确初始化,root_device_unregister()在访问设备结构成员时会触发空指针解引用或访问非法内存地址,导致通用保护故障(general protection fault)。
从崩溃栈可以看出,RIP指向root_device_unregister+0x26/0x60,表明问题发生在注销设备时访问设备结构体的过程中。KASAN报告的空指针解引用范围[0x0000000000000460-0x0000000000000467]进一步证实了设备结构体未被正确初始化。
利用方式:本地攻击者只需加载并卸载VME相关内核模块即可触发此漏洞。具体步骤为:1)以低权限用户身份执行modprobe或insmod加载VME模块;2)模块加载时fake_init()中的__root_device_register()调用失败;3)执行rmmod或modprobe -r卸载模块;4)模块退出时尝试注销未正确初始化的vme_root,触发内核崩溃。
修复方案是在fake_init()函数中添加对__root_device_register()返回值的检查,当注册失败时返回相应的错误码,阻止模块在初始化失败的情况下继续运行。