CVE-2023-53621CVE-2023-53621是Linux内核内存控制组(memcontrol)子系统中的一个高危空指针解引用漏洞,CVSS评分为7.8。该漏洞位于内核的回收最近性检查(eviction recency check)路径中,当系统尝试通过存储在shadow entry中的memcg ID来检索folio被回收时所属的内存控制组时,由于ID重用机制的存在,可能检索到一个尚未正确附加到memcg层级结构的新memcg对象。当在memcg分配与正确附加到层级结构之间的时间窗口内进行检索时,会在mem_cgroup_get_nr_swap_pages()函数执行层级遍历时触发空指针解引用,导致内核崩溃(kernel panic)。该漏洞可被本地低权限用户触发,通过调用pread64等系统调用触发文件读取操作,间接触发workingset_refault路径,最终在内核态导致系统拒绝服务(DoS)。由于该漏洞影响内核态的核心内存管理子系统,且具有本地权限提升和系统崩溃的潜在风险,被评定为高危漏洞。
该漏洞的根本原因在于memcg ID的发布时机不当。在Linux内核的memcontrol子系统中,每个内存控制组(memcg)都有一个唯一的ID,当旧的memcg被销毁后,其ID可能会被新分配的memcg重用。在eviction recency check路径中,内核通过存储在shadow entry中的memcg ID来查找对应的memcg对象。然而,存在以下竞争条件:
1. 当旧memcg被销毁后,其ID被释放到ID分配池中
2. 新memcg被分配并获得相同的ID,但此时尚未完成memcg层级结构的附加操作
3. 在此时间窗口内,如果另一个线程通过shadow entry中的旧ID查找memcg,会找到这个尚未初始化完成的新memcg
4. 调用mem_cgroup_get_nr_swap_pages()进行memcg层级遍历时,访问尚未初始化的层级指针,导致空指针解引用
漏洞触发路径为:用户态调用pread64系统调用 → filemap_read → page_cache_sync_ra → page_cache_ra_unbounded → filemap_add_folio → workingset_refault → workingset_test_recent → mem_cgroup_get_nr_swap_pages → 空指针解引用。
修复方案是将memcg的ID发布从分配阶段(alloc stage)移动到memcg正确附加到层级结构之后,确保通过ID检索到的memcg一定是已正确初始化的对象。