Skip to content

Commit 55c0ced

Browse files
ADSWT518Alexei Starovoitov
authored andcommitted
bpf: Reject negative offsets for ALU ops
When verifying BPF programs, the check_alu_op() function validates instructions with ALU operations. The 'offset' field in these instructions is a signed 16-bit integer. The existing check 'insn->off > 1' was intended to ensure the offset is either 0, or 1 for BPF_MOD/BPF_DIV. However, because 'insn->off' is signed, this check incorrectly accepts all negative values (e.g., -1). This commit tightens the validation by changing the condition to '(insn->off != 0 && insn->off != 1)'. This ensures that any value other than the explicitly permitted 0 and 1 is rejected, hardening the verifier against malformed BPF programs. Co-developed-by: Shenghao Yuan <[email protected]> Signed-off-by: Shenghao Yuan <[email protected]> Co-developed-by: Tianci Cao <[email protected]> Signed-off-by: Tianci Cao <[email protected]> Signed-off-by: Yazhou Tang <[email protected]> Acked-by: Yonghong Song <[email protected]> Fixes: ec0e2da ("bpf: Support new signed div/mod instructions.") Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 1bd3773 commit 55c0ced

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

kernel/bpf/verifier.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15804,7 +15804,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
1580415804
} else { /* all other ALU ops: and, sub, xor, add, ... */
1580515805

1580615806
if (BPF_SRC(insn->code) == BPF_X) {
15807-
if (insn->imm != 0 || insn->off > 1 ||
15807+
if (insn->imm != 0 || (insn->off != 0 && insn->off != 1) ||
1580815808
(insn->off == 1 && opcode != BPF_MOD && opcode != BPF_DIV)) {
1580915809
verbose(env, "BPF_ALU uses reserved fields\n");
1581015810
return -EINVAL;
@@ -15814,7 +15814,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
1581415814
if (err)
1581515815
return err;
1581615816
} else {
15817-
if (insn->src_reg != BPF_REG_0 || insn->off > 1 ||
15817+
if (insn->src_reg != BPF_REG_0 || (insn->off != 0 && insn->off != 1) ||
1581815818
(insn->off == 1 && opcode != BPF_MOD && opcode != BPF_DIV)) {
1581915819
verbose(env, "BPF_ALU uses reserved fields\n");
1582015820
return -EINVAL;

0 commit comments

Comments
 (0)