CVE-2023-53596CVE-2023-53596是Linux内核中drivers/base模块的一个高危漏洞,主要涉及设备资源(devres)管理机制中的内存泄漏问题。在当前的内核代码中,devres_release_all()函数仅在设备拥有总线(bus)且已被探测(probed)时才会被调用。当使用无总线(bus-less)或无驱动(driver-less)的设备时,如果某个托管资源持有对设备的引用,设备可能永远无法被释放,从而导致内存泄漏。该漏洞在DRM(Direct Rendering Manager)框架中尤为突出。攻击者可以利用此漏洞通过精心构造的操作触发内存泄漏或资源未释放问题,可能导致系统可用资源耗尽,进而引发拒绝服务(DoS)攻击。该漏洞的CVSS评分为7.8,属于高危级别,攻击者需要本地低权限访问即可利用,无需用户交互,但对系统的机密性、完整性和可用性均有高影响。修复方案是在device_del()函数中也调用devres_release_all(),确保设备注销时无论是否拥有总线或驱动,都能正确执行设备托管操作。
从技术层面分析,该漏洞的核心问题在于Linux内核设备资源管理(devres)子系统中设备注销流程的缺陷。
在Linux内核中,devres(Device Resource Management)是一种自动资源管理机制,允许驱动程序通过devm_*系列函数分配资源,当设备被销毁时这些资源会自动释放。正常情况下,devres_release_all()在device_release()中被调用以释放所有托管资源。
然而,当设备没有关联的总线或驱动时,devres_release_all()不会被调用。具体来说,device_release()函数中的逻辑会检查设备是否有总线以及是否已被探测,只有满足这些条件时才会执行资源释放。这导致了一个问题:如果一个托管资源(如通过devm_kzalloc等分配的内存)持有对设备本身的引用,由于设备永远不会被释放,该引用将永远存在,形成循环引用,导致内存泄漏。
此漏洞的利用方式相对简单:攻击者只需在内核中创建一个无总线或无驱动的设备,并为其分配托管资源。由于devres_release_all()不会被调用,分配的资源将永远不会被释放。攻击者可以重复此操作,持续消耗系统内存,最终导致内核内存耗尽,引发系统不稳定或拒绝服务。
修复方案结合了两个历史提交的优点:commit 2f8d16a996da(在device_del()中释放资源)和commit a525a3ddeaca(在device_release()中释放资源以避免内存泄漏)。最终的修复在device_del()和device_release()两个位置都调用devres_release_all(),确保资源在设备注销和释放时都能被正确释放。