Skip to content

Commit b9b34dd

Browse files
committed
bpf: Fix masking negation logic upon negative dst register
The negation logic for the case where the off_reg is sitting in the dst register is not correct given then we cannot just invert the add to a sub or vice versa. As a fix, perform the final bitwise and-op unconditionally into AX from the off_reg, then move the pointer from the src to dst and finally use AX as the source for the original pointer arithmetic operation such that the inversion yields a correct result. The single non-AX mov in between is possible given constant blinding is retaining it as it's not an immediate based operation. Fixes: 979d63d ("bpf: prevent out of bounds speculation on pointer arithmetic") Signed-off-by: Daniel Borkmann <[email protected]> Tested-by: Piotr Krysiuk <[email protected]> Reviewed-by: Piotr Krysiuk <[email protected]> Reviewed-by: John Fastabend <[email protected]> Acked-by: Alexei Starovoitov <[email protected]>
1 parent f80f88f commit b9b34dd

File tree

1 file changed

+4
-8
lines changed

1 file changed

+4
-8
lines changed

kernel/bpf/verifier.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12391,14 +12391,10 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
1239112391
*patch++ = BPF_ALU64_REG(BPF_OR, BPF_REG_AX, off_reg);
1239212392
*patch++ = BPF_ALU64_IMM(BPF_NEG, BPF_REG_AX, 0);
1239312393
*patch++ = BPF_ALU64_IMM(BPF_ARSH, BPF_REG_AX, 63);
12394-
if (issrc) {
12395-
*patch++ = BPF_ALU64_REG(BPF_AND, BPF_REG_AX,
12396-
off_reg);
12397-
insn->src_reg = BPF_REG_AX;
12398-
} else {
12399-
*patch++ = BPF_ALU64_REG(BPF_AND, off_reg,
12400-
BPF_REG_AX);
12401-
}
12394+
*patch++ = BPF_ALU64_REG(BPF_AND, BPF_REG_AX, off_reg);
12395+
if (!issrc)
12396+
*patch++ = BPF_MOV64_REG(insn->dst_reg, insn->src_reg);
12397+
insn->src_reg = BPF_REG_AX;
1240212398
if (isneg)
1240312399
insn->code = insn->code == code_add ?
1240412400
code_sub : code_add;

0 commit comments

Comments
 (0)