mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
bpf: Reject negative offsets for ALU ops
[ Upstream commit55c0ced59f] 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 <shenghaoyuan0928@163.com> Signed-off-by: Shenghao Yuan <shenghaoyuan0928@163.com> Co-developed-by: Tianci Cao <ziye@zju.edu.cn> Signed-off-by: Tianci Cao <ziye@zju.edu.cn> Signed-off-by: Yazhou Tang <tangyazhou518@outlook.com> Acked-by: Yonghong Song <yonghong.song@linux.dev> Fixes:ec0e2da95f("bpf: Support new signed div/mod instructions.") Link: https://lore.kernel.org/r/tencent_70D024BAE70A0A309A4781694C7B764B0608@qq.com Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
b9ef496322
commit
21167bf70d
@@ -15755,7 +15755,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
|
||||
} else { /* all other ALU ops: and, sub, xor, add, ... */
|
||||
|
||||
if (BPF_SRC(insn->code) == BPF_X) {
|
||||
if (insn->imm != 0 || insn->off > 1 ||
|
||||
if (insn->imm != 0 || (insn->off != 0 && insn->off != 1) ||
|
||||
(insn->off == 1 && opcode != BPF_MOD && opcode != BPF_DIV)) {
|
||||
verbose(env, "BPF_ALU uses reserved fields\n");
|
||||
return -EINVAL;
|
||||
@@ -15765,7 +15765,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
if (insn->src_reg != BPF_REG_0 || insn->off > 1 ||
|
||||
if (insn->src_reg != BPF_REG_0 || (insn->off != 0 && insn->off != 1) ||
|
||||
(insn->off == 1 && opcode != BPF_MOD && opcode != BPF_DIV)) {
|
||||
verbose(env, "BPF_ALU uses reserved fields\n");
|
||||
return -EINVAL;
|
||||
|
||||
Reference in New Issue
Block a user