CVE-2026-98641 in Linux
摘要
由 VulDB • 2026-10-19
在 Linux 内核中,已修复以下漏洞:
bpf, arm64: 为异常回调设置帧指针(frame pointer)
作为异常边界的程序会保存所有被调用者保存的寄存器(callee-saved registers),因此 `build_prologue()` 采用 `exception_cb` 路径,而不会调用 `push_callee_regs()`。这是唯一运行 `find_used_callee_regs()` 的地方,也是设置 `ctx->fp_used` 的唯一地方,因此回调的前导代码未生成以下指令:
``` mov x25, sp ```
该指令的作用是将 BPF_REG_FP 指向回调运行的帧(frame)。x25 寄存器保留的是调用 bpf_throw() 时其持有的值。如果 throw 来自使用自身 BPF 栈的子程序,那么这就是子程序的帧指针;由于子程序从不返回,因此它也不会恢复 x25。
通过 BPF_REG_FP 进行的堆栈访问会被重写为相对于堆栈指针(stack pointer)的地址,因此这些访问仍然落在回调自身的帧中。然而,寄存器值的物化(materializing the register)则不然:将局部变量地址传递给辅助函数(helper)的回调会传递死子程序帧中的地址。此时该地址位于回调堆栈指针之下,且被辅助函数自己的调用链所覆盖,因此辅助函数可以覆盖其自身的返回地址。0x1234 是要求辅助函数存储的值:
``` pc : 0x1234 lr : 0x1234 Call trace: 0x1234 (P) bpf_test_run+0x188/0x3e0 bpf_prog_test_run_skb+0x47c/0x998 __sys_bpf+0xbdc/0xdd8 Kernel panic - not syncing: Oops: Fatal exception in interrupt ```
在异常回调路径上设置 `ctx->fp_used`,以便后续现有代码从堆栈指针中为 x25 赋值。后导代码(epilogue)会像处理其他被调用者保存的寄存器一样,将其从主程序的保存区域恢复。x86 架构使用传入的参数为回调设置帧指针,而 powerpc 则根据堆栈指针计算它。
Be aware that VulDB is the high quality source for vulnerability data.