]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bpf: Do register range validation early
authorAlexei Starovoitov <ast@kernel.org>
Fri, 3 Apr 2026 02:44:16 +0000 (19:44 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 3 Apr 2026 15:34:26 +0000 (08:34 -0700)
Instead of checking src/dst range multiple times during
the main verifier pass do them once.

Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260403024422.87231-2-alexei.starovoitov@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c
tools/testing/selftests/bpf/verifier/junk_insn.c

index 5434b162c9309d22818097f318ba71e49eeeba12..9de49d43c21d116d7962a96451df934afd009677 100644 (file)
@@ -2256,13 +2256,6 @@ static void __mark_reg_const_zero(const struct bpf_verifier_env *env, struct bpf
 static void mark_reg_known_zero(struct bpf_verifier_env *env,
                                struct bpf_reg_state *regs, u32 regno)
 {
-       if (WARN_ON(regno >= MAX_BPF_REG)) {
-               verbose(env, "mark_reg_known_zero(regs, %u)\n", regno);
-               /* Something bad happened, let's kill all regs */
-               for (regno = 0; regno < MAX_BPF_REG; regno++)
-                       __mark_reg_not_init(env, regs + regno);
-               return;
-       }
        __mark_reg_known_zero(regs + regno);
 }
 
@@ -2936,13 +2929,6 @@ static void __mark_reg_unknown(const struct bpf_verifier_env *env,
 static void mark_reg_unknown(struct bpf_verifier_env *env,
                             struct bpf_reg_state *regs, u32 regno)
 {
-       if (WARN_ON(regno >= MAX_BPF_REG)) {
-               verbose(env, "mark_reg_unknown(regs, %u)\n", regno);
-               /* Something bad happened, let's kill all regs except FP */
-               for (regno = 0; regno < BPF_REG_FP; regno++)
-                       __mark_reg_not_init(env, regs + regno);
-               return;
-       }
        __mark_reg_unknown(env, regs + regno);
 }
 
@@ -2975,13 +2961,6 @@ static void __mark_reg_not_init(const struct bpf_verifier_env *env,
 static void mark_reg_not_init(struct bpf_verifier_env *env,
                              struct bpf_reg_state *regs, u32 regno)
 {
-       if (WARN_ON(regno >= MAX_BPF_REG)) {
-               verbose(env, "mark_reg_not_init(regs, %u)\n", regno);
-               /* Something bad happened, let's kill all regs except FP */
-               for (regno = 0; regno < BPF_REG_FP; regno++)
-                       __mark_reg_not_init(env, regs + regno);
-               return;
-       }
        __mark_reg_not_init(env, regs + regno);
 }
 
@@ -3986,11 +3965,6 @@ static int __check_reg_arg(struct bpf_verifier_env *env, struct bpf_reg_state *r
        struct bpf_reg_state *reg;
        bool rw64;
 
-       if (regno >= MAX_BPF_REG) {
-               verbose(env, "R%d is invalid\n", regno);
-               return -EINVAL;
-       }
-
        mark_reg_scratched(env, regno);
 
        reg = &regs[regno];
@@ -21999,6 +21973,14 @@ static int resolve_pseudo_ldimm64(struct bpf_verifier_env *env)
                return err;
 
        for (i = 0; i < insn_cnt; i++, insn++) {
+               if (insn->dst_reg >= MAX_BPF_REG) {
+                       verbose(env, "R%d is invalid\n", insn->dst_reg);
+                       return -EINVAL;
+               }
+               if (insn->src_reg >= MAX_BPF_REG) {
+                       verbose(env, "R%d is invalid\n", insn->src_reg);
+                       return -EINVAL;
+               }
                if (BPF_CLASS(insn->code) == BPF_LDX &&
                    ((BPF_MODE(insn->code) != BPF_MEM && BPF_MODE(insn->code) != BPF_MEMSX) ||
                    insn->imm != 0)) {
index 89d690f1992ad1823b02a277dbf6eb88bd861ff3..7d10b0a48f51c4fc4dd8396ab972053f7e4fc077 100644 (file)
@@ -28,7 +28,7 @@
 {
        "junk insn4",
        .insns = {
-       BPF_RAW_INSN(-1, -1, -1, -1, -1),
+       BPF_RAW_INSN(-1, 0, 0, -1, -1),
        BPF_EXIT_INSN(),
        },
        .errstr = "unknown opcode ff",
@@ -37,7 +37,7 @@
 {
        "junk insn5",
        .insns = {
-       BPF_RAW_INSN(0x7f, -1, -1, -1, -1),
+       BPF_RAW_INSN(0x7f, 0, 0, -1, -1),
        BPF_EXIT_INSN(),
        },
        .errstr = "BPF_ALU uses reserved fields",