mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-10 22:50:07 -04:00
bpf: Don't resurrect a scalar id dropped by collect_linked_regs()
check_cond_jmp_op() copies the compared registers into
env->{false,true}_reg{1,2} before collect_linked_regs() runs and copies
those snapshots back into both branch states afterwards.
collect_linked_regs() records at most LINKED_REGS_MAX members of a
linked registers group in the jump history and calls clear_scalar_id()
for every member that does not fit. The compared register is not exempt
from that.
As a consequence, sync_linked_regs() might adjust ranges for more
registers than bpf_bt_sync_linked_regs() can propagate precision to.
Collect the linked registers before the snapshots are taken instead.
This might lead to some unnecessary clear_scalar_id's, but from
previous testing situations with many linked registers are
extremely rare.
Fixes: ec1d77cb0e ("bpf: Use bpf_verifier_env buffers for reg_set_min_max")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20260904083325.2083493-3-eddyz87@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
This commit is contained in:
committed by
Kumar Kartikeya Dwivedi
parent
6752b90ccf
commit
73a98f9681
@@ -16898,6 +16898,16 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Collect the linked registers before env->{true,false}_reg{1,2} setup,
|
||||
* otherwise ids dropped by collect_linked_regs() would be resurrected
|
||||
* when env->{true,false}_reg{1,2} are copied back.
|
||||
*/
|
||||
if (BPF_SRC(insn->code) == BPF_X && src_reg->type == SCALAR_VALUE && src_reg->id)
|
||||
collect_linked_regs(env, this_branch, src_reg->id, &linked_regs);
|
||||
if (dst_reg->type == SCALAR_VALUE && dst_reg->id)
|
||||
collect_linked_regs(env, this_branch, dst_reg->id, &linked_regs);
|
||||
|
||||
is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32;
|
||||
env->false_reg1 = *dst_reg;
|
||||
env->false_reg2 = *src_reg;
|
||||
@@ -16952,10 +16962,6 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
|
||||
* 'this_branch' and 'other_branch' share this history
|
||||
* if parent state is created.
|
||||
*/
|
||||
if (BPF_SRC(insn->code) == BPF_X && src_reg->type == SCALAR_VALUE && src_reg->id)
|
||||
collect_linked_regs(env, this_branch, src_reg->id, &linked_regs);
|
||||
if (dst_reg->type == SCALAR_VALUE && dst_reg->id)
|
||||
collect_linked_regs(env, this_branch, dst_reg->id, &linked_regs);
|
||||
if (linked_regs.cnt > 1) {
|
||||
err = bpf_push_jmp_history(env, this_branch, 0, 0, 0, linked_regs_pack(&linked_regs));
|
||||
if (err)
|
||||
|
||||
Reference in New Issue
Block a user