mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-10 15:49:01 -04:00
bpf: Don't predict JMP32 pointer vs zero comparisons
Consider the following program:
r1 = map_value; /* low 32 bits are zero at runtime */
r6 = 0xdead000000000000;
if w1 != 0 goto l1;
l0: r1 += r6;
r2 = *(u64 *)(r1 + 0);
exit;
l1: r6 = 0;
goto l0;
At the moment is_branch_taken() reports the jump as always taken,
because it does not distinguish between BPF_JMP and BPF_JMP32
comparisons when processing 'if w1 != 0 ...'.
Fixes: cac616db39 ("bpf: Verifier track null pointer branch_taken with JNE and JEQ")
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-5-eddyz87@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
This commit is contained in:
committed by
Kumar Kartikeya Dwivedi
parent
bc412b3fb1
commit
e51179a4e0
@@ -16337,6 +16337,13 @@ static int is_branch_taken(struct bpf_verifier_env *env, struct bpf_reg_state *r
|
||||
if (__is_pointer_value(false, reg1) || __is_pointer_value(false, reg2)) {
|
||||
u64 val;
|
||||
|
||||
/*
|
||||
* The low 32 bits of a valid pointer may well be zero, hence
|
||||
* nothing below applies to a 32-bit comparison.
|
||||
*/
|
||||
if (is_jmp32)
|
||||
return -1;
|
||||
|
||||
/* arrange that reg2 is a scalar, and reg1 is a pointer */
|
||||
if (!is_reg_const(reg2, is_jmp32)) {
|
||||
opcode = flip_opcode(opcode);
|
||||
|
||||
Reference in New Issue
Block a user