]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - kernel/bpf/verifier.c
treewide: kzalloc() -> kcalloc()
[mirror_ubuntu-hirsute-kernel.git] / kernel / bpf / verifier.c
index d6403b5166f4934e733f53367b82c0d468ba32cb..1494e087890e73c07f678ea75c91e6e15506e84c 100644 (file)
@@ -1617,6 +1617,30 @@ static int get_callee_stack_depth(struct bpf_verifier_env *env,
 }
 #endif
 
+static int check_ctx_reg(struct bpf_verifier_env *env,
+                        const struct bpf_reg_state *reg, int regno)
+{
+       /* Access to ctx or passing it to a helper is only allowed in
+        * its original, unmodified form.
+        */
+
+       if (reg->off) {
+               verbose(env, "dereference of modified ctx ptr R%d off=%d disallowed\n",
+                       regno, reg->off);
+               return -EACCES;
+       }
+
+       if (!tnum_is_const(reg->var_off) || reg->var_off.value) {
+               char tn_buf[48];
+
+               tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
+               verbose(env, "variable ctx access var_off=%s disallowed\n", tn_buf);
+               return -EACCES;
+       }
+
+       return 0;
+}
+
 /* truncate register to smaller size (in bytes)
  * must be called with size < BPF_REG_SIZE
  */
@@ -1686,24 +1710,11 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
                        verbose(env, "R%d leaks addr into ctx\n", value_regno);
                        return -EACCES;
                }
-               /* ctx accesses must be at a fixed offset, so that we can
-                * determine what type of data were returned.
-                */
-               if (reg->off) {
-                       verbose(env,
-                               "dereference of modified ctx ptr R%d off=%d+%d, ctx+const is allowed, ctx+const+const is not\n",
-                               regno, reg->off, off - reg->off);
-                       return -EACCES;
-               }
-               if (!tnum_is_const(reg->var_off) || reg->var_off.value) {
-                       char tn_buf[48];
 
-                       tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
-                       verbose(env,
-                               "variable ctx access var_off=%s off=%d size=%d",
-                               tn_buf, off, size);
-                       return -EACCES;
-               }
+               err = check_ctx_reg(env, reg, regno);
+               if (err < 0)
+                       return err;
+
                err = check_ctx_access(env, insn_idx, off, size, t, &reg_type);
                if (!err && t == BPF_READ && value_regno >= 0) {
                        /* ctx access returns either a scalar, or a
@@ -1984,6 +1995,9 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 regno,
                expected_type = PTR_TO_CTX;
                if (type != expected_type)
                        goto err_type;
+               err = check_ctx_reg(env, reg, regno);
+               if (err < 0)
+                       return err;
        } else if (arg_type_is_mem_ptr(arg_type)) {
                expected_type = PTR_TO_STACK;
                /* One exception here. In case function allows for NULL to be
@@ -5433,7 +5447,7 @@ static int jit_subprogs(struct bpf_verifier_env *env)
                insn->imm = 1;
        }
 
-       func = kzalloc(sizeof(prog) * env->subprog_cnt, GFP_KERNEL);
+       func = kcalloc(env->subprog_cnt, sizeof(prog), GFP_KERNEL);
        if (!func)
                return -ENOMEM;