mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 13:41:48 -04:00
bpf: Fix linked reg delta tracking when src_reg == dst_reg
Consider the case of rX += rX where src_reg and dst_reg are pointers to
the same bpf_reg_state in adjust_reg_min_max_vals(). The latter first
modifies the dst_reg in-place, and later in the delta tracking, the
subsequent is_reg_const(src_reg)/reg_const_value(src_reg) reads the
post-{add,sub} value instead of the original source.
This is problematic since it sets an incorrect delta, which sync_linked_regs()
then propagates to linked registers, thus creating a verifier-vs-runtime
mismatch. Fix it by just skipping this corner case.
Fixes: 98d7ca374b ("bpf: Track delta between "linked" registers.")
Reported-by: STAR Labs SG <info@starlabs.sg>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/r/20260407192421.508817-1-daniel@iogearbox.net
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
committed by
Alexei Starovoitov
parent
656e835bb0
commit
d7f14173c0
@@ -16722,7 +16722,8 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
|
||||
*/
|
||||
if (env->bpf_capable &&
|
||||
(BPF_OP(insn->code) == BPF_ADD || BPF_OP(insn->code) == BPF_SUB) &&
|
||||
dst_reg->id && is_reg_const(src_reg, alu32)) {
|
||||
dst_reg->id && is_reg_const(src_reg, alu32) &&
|
||||
!(BPF_SRC(insn->code) == BPF_X && insn->src_reg == insn->dst_reg)) {
|
||||
u64 val = reg_const_value(src_reg, alu32);
|
||||
s32 off;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user