Mark these cases as non-recoverable to later prevent them from being
caught when they occur during speculative path verification.

Eduard writes [1]:

  The only pace I'm aware of that might act upon specific error code
  from verifier syscall is libbpf. Looking through libbpf code, it seems
  that this change does not interfere with libbpf.

[1] 
https://lore.kernel.org/all/785b4531ce3b44a84059a4feb4ba458c68fce719.ca...@gmail.com/

Signed-off-by: Luis Gerhorst <luis.gerho...@fau.de>
Reviewed-by: Eduard Zingerman <eddy...@gmail.com>
Acked-by: Henriette Herzog <henriette.her...@rub.de>
Cc: Maximilian Ott <o...@cs.fau.de>
Cc: Milan Stephan <milan.step...@fau.de>
---
 kernel/bpf/verifier.c | 36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index c4f197ca6c45..55c1d7ada098 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -8965,7 +8965,7 @@ static int resolve_map_arg_type(struct bpf_verifier_env 
*env,
        if (!meta->map_ptr) {
                /* kernel subsystem misconfigured verifier */
                verbose(env, "invalid map_ptr to access map->type\n");
-               return -EACCES;
+               return -EFAULT;
        }
 
        switch (meta->map_ptr->map_type) {
@@ -9653,7 +9653,7 @@ static int check_func_arg(struct bpf_verifier_env *env, 
u32 arg,
                         * that kernel subsystem misconfigured verifier
                         */
                        verbose(env, "invalid map_ptr to access map->key\n");
-                       return -EACCES;
+                       return -EFAULT;
                }
                key_size = meta->map_ptr->key_size;
                err = check_helper_mem_access(env, regno, key_size, BPF_READ, 
false, NULL);
@@ -9680,7 +9680,7 @@ static int check_func_arg(struct bpf_verifier_env *env, 
u32 arg,
                if (!meta->map_ptr) {
                        /* kernel subsystem misconfigured verifier */
                        verbose(env, "invalid map_ptr to access map->value\n");
-                       return -EACCES;
+                       return -EFAULT;
                }
                meta->raw_mode = arg_type & MEM_UNINIT;
                err = check_helper_mem_access(env, regno, 
meta->map_ptr->value_size,
@@ -10979,7 +10979,7 @@ record_func_map(struct bpf_verifier_env *env, struct 
bpf_call_arg_meta *meta,
 
        if (map == NULL) {
                verbose(env, "kernel subsystem misconfigured verifier\n");
-               return -EINVAL;
+               return -EFAULT;
        }
 
        /* In case of read-only, some additional restrictions
@@ -11018,7 +11018,7 @@ record_func_key(struct bpf_verifier_env *env, struct 
bpf_call_arg_meta *meta,
                return 0;
        if (!map || map->map_type != BPF_MAP_TYPE_PROG_ARRAY) {
                verbose(env, "kernel subsystem misconfigured verifier\n");
-               return -EINVAL;
+               return -EFAULT;
        }
 
        reg = &regs[BPF_REG_3];
@@ -11272,7 +11272,7 @@ static int check_helper_call(struct bpf_verifier_env 
*env, struct bpf_insn *insn
        if (changes_data && fn->arg1_type != ARG_PTR_TO_CTX) {
                verbose(env, "kernel subsystem misconfigured func %s#%d: r1 != 
ctx\n",
                        func_id_name(func_id), func_id);
-               return -EINVAL;
+               return -EFAULT;
        }
 
        memset(&meta, 0, sizeof(meta));
@@ -11574,7 +11574,7 @@ static int check_helper_call(struct bpf_verifier_env 
*env, struct bpf_insn *insn
                if (meta.map_ptr == NULL) {
                        verbose(env,
                                "kernel subsystem misconfigured verifier\n");
-                       return -EINVAL;
+                       return -EFAULT;
                }
 
                if (func_id == BPF_FUNC_map_lookup_elem &&
@@ -16697,7 +16697,7 @@ static int check_ld_imm(struct bpf_verifier_env *env, 
struct bpf_insn *insn)
                dst_reg->type = CONST_PTR_TO_MAP;
        } else {
                verbose(env, "bpf verifier is misconfigured\n");
-               return -EINVAL;
+               return -EFAULT;
        }
 
        return 0;
@@ -16744,7 +16744,7 @@ static int check_ld_abs(struct bpf_verifier_env *env, 
struct bpf_insn *insn)
 
        if (!env->ops->gen_ld_abs) {
                verbose(env, "bpf verifier is misconfigured\n");
-               return -EINVAL;
+               return -EFAULT;
        }
 
        if (insn->dst_reg != BPF_REG_0 || insn->off != 0 ||
@@ -20781,7 +20781,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env 
*env)
                                                 -(subprogs[0].stack_depth + 
8));
                if (epilogue_cnt >= INSN_BUF_SIZE) {
                        verbose(env, "bpf verifier is misconfigured\n");
-                       return -EINVAL;
+                       return -EFAULT;
                } else if (epilogue_cnt) {
                        /* Save the ARG_PTR_TO_CTX for the epilogue to use */
                        cnt = 0;
@@ -20804,13 +20804,13 @@ static int convert_ctx_accesses(struct 
bpf_verifier_env *env)
        if (ops->gen_prologue || env->seen_direct_write) {
                if (!ops->gen_prologue) {
                        verbose(env, "bpf verifier is misconfigured\n");
-                       return -EINVAL;
+                       return -EFAULT;
                }
                cnt = ops->gen_prologue(insn_buf, env->seen_direct_write,
                                        env->prog);
                if (cnt >= INSN_BUF_SIZE) {
                        verbose(env, "bpf verifier is misconfigured\n");
-                       return -EINVAL;
+                       return -EFAULT;
                } else if (cnt) {
                        new_prog = bpf_patch_insn_data(env, 0, insn_buf, cnt);
                        if (!new_prog)
@@ -20967,7 +20967,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env 
*env)
 
                        if (type == BPF_WRITE) {
                                verbose(env, "bpf verifier narrow ctx access 
misconfigured\n");
-                               return -EINVAL;
+                               return -EFAULT;
                        }
 
                        size_code = BPF_H;
@@ -20986,7 +20986,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env 
*env)
                if (cnt == 0 || cnt >= INSN_BUF_SIZE ||
                    (ctx_field_size && !target_size)) {
                        verbose(env, "bpf verifier is misconfigured\n");
-                       return -EINVAL;
+                       return -EFAULT;
                }
 
                if (is_narrower_load && size < target_size) {
@@ -20994,7 +20994,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env 
*env)
                                off, size, size_default) * 8;
                        if (shift && cnt + 1 >= INSN_BUF_SIZE) {
                                verbose(env, "bpf verifier narrow ctx load 
misconfigured\n");
-                               return -EINVAL;
+                               return -EFAULT;
                        }
                        if (ctx_field_size <= 4) {
                                if (shift)
@@ -21757,7 +21757,7 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
                        cnt = env->ops->gen_ld_abs(insn, insn_buf);
                        if (cnt == 0 || cnt >= INSN_BUF_SIZE) {
                                verbose(env, "bpf verifier is misconfigured\n");
-                               return -EINVAL;
+                               return -EFAULT;
                        }
 
                        new_prog = bpf_patch_insn_data(env, i + delta, 
insn_buf, cnt);
@@ -22093,7 +22093,7 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
                                        goto patch_map_ops_generic;
                                if (cnt <= 0 || cnt >= INSN_BUF_SIZE) {
                                        verbose(env, "bpf verifier is 
misconfigured\n");
-                                       return -EINVAL;
+                                       return -EFAULT;
                                }
 
                                new_prog = bpf_patch_insn_data(env, i + delta,
@@ -22453,7 +22453,7 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
                    !map_ptr->ops->map_poke_untrack ||
                    !map_ptr->ops->map_poke_run) {
                        verbose(env, "bpf verifier is misconfigured\n");
-                       return -EINVAL;
+                       return -EFAULT;
                }
 
                ret = map_ptr->ops->map_poke_track(map_ptr, prog->aux);
-- 
2.49.0


Reply via email to