CVE-2023-53634CVE-2023-53634是Linux内核arm64架构中BPF(Berkeley Packet Filter)子系统的一个安全漏洞。当BPF trampoline使用BPF_TRAMP_F_CALL_ORIG标志时,会通过BLR指令跳转回调用点之后的指令以调用被patch的函数。对于启用了BTI(Branch Target Identification,分支目标识别)的内核,调用点之后的指令通常是PACIASP,在这种情况下使用BLR跳转是安全的。但是当调用点后面不是PACIASP或bti指令时,会触发BTI异常,导致内核panic。
该漏洞在运行BPF测试程序(test_progs)时被发现,触发时系统会输出"Unhandled 64-bit el1h sync exception on CPU0, ESR 0x0000000034000002 -- BTI"的错误日志,并导致"Kernel panic - not syncing: Unhandled exception"。漏洞的根本原因在于BPF trampoline生成代码时没有考虑到调用点之后的指令可能不是BTI兼容指令(如PACIASP),导致BTI分支目标检查失败。
此漏洞的CVSS评分为5.5,属于中危级别。攻击向量为本地(AV:L),需要低权限(PR:L),无需用户交互(UI:N)。虽然机密性和完整性影响为低和无,但可用性影响为高(A:H),因为触发该漏洞会导致内核panic,造成系统拒绝服务。
该漏洞的技术原理涉及arm64架构的BTI(Branch Target Identification)机制和BPF trampoline的代码生成逻辑。
BTI是armv8.5-A引入的一种安全特性,用于防止分支目标被恶意篡改。BTI通过在合法分支目标处放置BTI指令(如BTI C),并在分支指令(如BLR)执行时检查目标地址是否包含有效的BTI指令来工作。如果目标地址没有BTI指令,则触发异常。
在Linux内核的BPF trampoline实现中,当设置了BPF_TRAMP_F_CALL_ORIG标志时,trampoline需要调用原始的被patch函数。它使用BLR指令跳转到调用点之后的指令。对于BPF程序,JIT编译器总是在调用点之后放置PACIASP指令(用于PAC指针认证),因此BTI检查可以通过。
但是,对于普通的内核函数(如bpf_fentry_test1),调用点之后的指令可能不是PACIASP。例如在漏洞触发的场景中,调用点之后的指令是ADD指令,不是PACIASP。当BPF trampoline使用BLR跳转到这个ADD指令时,由于该地址没有BTI指令,触发了BTI异常。
修复方案是将BLR指令替换为RET指令。RET指令不受BTI分支目标检查的约束,因此可以安全地跳转到任何地址。通过这种方式,BPF trampoline可以绕过BTI检查,避免触发异常。
利用方式:本地用户可以通过加载特定的BPF程序(如使用bpf()系统调用)并触发BPF trampoline执行来触发该漏洞,导致内核panic和系统拒绝服务。