CVE-2023-53645CVE-2023-53645是Linux内核BPF(Berkeley Packet Filter)子系统中存在的一个高危释放后使用(Use-After-Free)漏洞。该漏洞源于bpf_refcount_acquire函数的一个错误假设:原始的bpf_refcount系列补丁认为BPF程序调用bpf_refcount_acquire时总能保证目标节点是存活的。然而,当bpf_rbtree_add或list_push_{front,back}操作失败时,会调用bpf_obj_drop释放节点,导致非拥有引用(non-owning refs)的引用计数可能被减至0,从而引发释放后使用漏洞。攻击者在拥有低权限的情况下,可通过精心构造的BPF程序触发该漏洞,导致内核崩溃或权限提升。该漏洞的CVSS评分为7.8,属于高危级别,攻击向量为本地攻击,需要低权限但无需用户交互,对机密性、完整性和可用性均有高影响。此漏洞已在Linux内核6.3.0-rc7及更早版本中存在,影响多个稳定版本的内核。
该漏洞的核心问题在于BPF程序中bpf_refcount_acquire函数的语义不正确。原始实现使用refcount_inc进行引用计数增加,假设目标节点必定存活。但在特定场景下,当BPF程序执行bpf_rbtree_add失败时,bpf_rbtree_add内部会调用bpf_obj_drop释放节点,而此时BPF程序仍持有对该节点的引用但已失去所有权保护。如果在bpf_refcount_acquire执行之前,其他路径将引用计数减至0,节点将被释放,随后bpf_refcount_acquire将对已释放的内存执行refcount_inc操作,触发内核警告"refcount_t: addition on 0; use-after-free"。
利用方式:攻击者需要编写一个BPF程序,在临界区内调用bpf_rbtree_add,并故意触发其失败路径,随后调用bpf_refcount_acquire。具体攻击代码模式如下:
1. 使用bpf_kptr_xchg从map中获取节点;
2. 获取自旋锁后调用bpf_rbtree_add;
3. 当add失败时,节点被bpf_obj_drop释放;
4. 紧接着调用bpf_refcount_acquire尝试增加已释放节点的引用计数。
修复方案是将bpf_refcount_acquire_impl中的refcount_inc替换为refcount_inc_not_zero,并标记bpf_refcount_acquire为KF_RET_NULL。对于拥有引用(owning refs),验证器会跟踪输入是否为拥有引用并相应处理。