@@ -7880,13 +7880,25 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
return -EINVAL;
}
- if ((opcode == BPF_LSH || opcode == BPF_RSH ||
- opcode == BPF_ARSH) && BPF_SRC(insn->code) == BPF_K) {
+ if (opcode == BPF_LSH || opcode == BPF_RSH ||
+ opcode == BPF_ARSH) {
int size = BPF_CLASS(insn->code) == BPF_ALU64 ? 64 : 32;
- if (insn->imm < 0 || insn->imm >= size) {
- verbose(env, "invalid shift %d\n", insn->imm);
- return -EINVAL;
+ if (BPF_SRC(insn->code) == BPF_K) {
+ if (insn->imm < 0 || insn->imm >= size) {
+ verbose(env, "invalid shift %d\n", insn->imm);
+ return -EINVAL;
+ }
+ }
+ if (BPF_SRC(insn->code) == BPF_X) {
+ struct bpf_reg_state *src_reg;
+
+ src_reg = ®s[insn->src_reg];
+ if (src_reg->umax_value >= size) {
+ verbose(env, "invalid shift %lld\n",
+ src_reg->umax_value);
+ return -EINVAL;
+ }
}
}
UBSAN: shift-out-of-bounds in kernel/bpf/core.c:1414:2 shift exponent 248 is too large for 32-bit type 'unsigned int' Reported-and-tested-by: syzbot+bed360704c521841c85d@syzkaller.appspotmail.com Signed-off-by: Kurt Manucredo <fuzzybritches0@gmail.com> --- https://syzkaller.appspot.com/bug?id=edb51be4c9a320186328893287bb30d5eed09231 Changelog: ---------- v3 - Make it clearer what the fix is for. v2 - Fix shift-out-of-bounds in ___bpf_prog_run() by adding boundary check in check_alu_op() in verifier.c. v1 - Fix shift-out-of-bounds in ___bpf_prog_run() by adding boundary check in ___bpf_prog_run(). Hi everyone, I hope this fixes it! kind regards kernel/bpf/verifier.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-)