diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/core.c | 9 | ||||
| -rw-r--r-- | kernel/bpf/fixups.c | 39 | ||||
| -rw-r--r-- | kernel/bpf/syscall.c | 4 | ||||
| -rw-r--r-- | kernel/bpf/verifier.c | 64 |
4 files changed, 16 insertions, 100 deletions
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 0a8ba603f44b..7cf37690d41f 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -2639,8 +2639,7 @@ static bool bpf_prog_select_interpreter(struct bpf_prog *fp) /* * Whether a function has an insn that works with the arena base, which a JIT * sets up in the prologue when bpf_prog_uses_arena_insns() says so. Decided on - * the final insns of the function: an access through an arena pointer, or - * through a number in a program loaded with BPF_F_ARENA_SCALAR, has been + * the final insns of the function: an access through an arena pointer has been * rewritten to a BPF_PROBE_MEM32 form by then, a cast to the user address * space keeps BPF_ADDR_SPACE_CAST, and a kfunc call with an __arena argument, * which the JIT rebases, has a function model that says so. A load of an @@ -3518,12 +3517,6 @@ bool __weak bpf_jit_supports_arena(void) return false; } -/* Whether JIT takes BPF_REG_AX as the address of arena access */ -bool __weak bpf_jit_supports_arena_scalar(void) -{ - return false; -} - bool __weak bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena) { return false; diff --git a/kernel/bpf/fixups.c b/kernel/bpf/fixups.c index f062ef7dd943..41bc37e205e0 100644 --- a/kernel/bpf/fixups.c +++ b/kernel/bpf/fixups.c @@ -44,31 +44,6 @@ static bool is_addr_space_cast32(struct bpf_prog *prog, const struct bpf_insn *i return false; } -/* - * The insn accesses arena through a number. JITs add the base of arena - * to the register as it is, so the access goes through the low 32 bits of - * the number in BPF_REG_AX. Registers of the program are not changed: the - * number may be compared or stored later, and on another path the register - * may be PTR_TO_ARENA. - * - * Constant blinding leaves insns that use BPF_REG_AX alone, so the immediate - * of st through a number is not blinded. - */ -static int arena_scalar_access(const struct bpf_insn *insn, struct bpf_insn *buf) -{ - bool load = BPF_CLASS(insn->code) == BPF_LDX || bpf_atomic_is_load_acq(insn); - struct bpf_insn *patch = buf; - - *patch++ = BPF_MOV32_REG(BPF_REG_AX, load ? insn->src_reg : insn->dst_reg); - *patch = *insn; - if (load) - patch->src_reg = BPF_REG_AX; - else - patch->dst_reg = BPF_REG_AX; - patch++; - return patch - buf; -} - /* Return the regno defined by the insn, or -1. */ static int insn_def_regno(const struct bpf_insn *insn) { @@ -1880,20 +1855,6 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env) /* Convert BPF_CLASS(insn->code) == BPF_ALU64 to 32-bit ALU */ insn->code = BPF_ALU | BPF_OP(insn->code) | BPF_SRC(insn->code); - if (env->insn_aux_data[i + delta].arena_scalar) { - cnt = arena_scalar_access(insn, insn_buf); - - new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt); - if (!new_prog) - return -ENOMEM; - - delta += cnt - 1; - prog = new_prog; - env->prog = prog; - insn = prog->insnsi + i + delta; - goto next_insn; - } - /* Make sdiv/smod divide-by-minus-one exceptions impossible. */ if ((insn->code == (BPF_ALU64 | BPF_MOD | BPF_K) || insn->code == (BPF_ALU64 | BPF_DIV | BPF_K) || diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 90bc7230afa8..60c4d84b9aba 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -2971,13 +2971,9 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, struct bpf_log_at BPF_F_XDP_HAS_FRAGS | BPF_F_XDP_DEV_BOUND_ONLY | BPF_F_TEST_REG_INVARIANTS | - BPF_F_ARENA_SCALAR | BPF_F_TOKEN_FD)) return -EINVAL; - if ((attr->prog_flags & BPF_F_ARENA_SCALAR) && !bpf_jit_supports_arena_scalar()) - return -EOPNOTSUPP; - bpf_prog_load_fixup_attach_type(attr); if (attr->prog_flags & BPF_F_TOKEN_FD) { diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index a0a5f075d201..c1070aba621b 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5500,19 +5500,6 @@ static bool is_arena_reg(struct bpf_verifier_env *env, int regno) return reg->type == PTR_TO_ARENA; } -/* - * There are no address spaces in Rust, addresses of arena are plain numbers. - * When the program is loaded with BPF_F_ARENA_SCALAR and has an arena a load or - * a store through a number is an access to arena at the low 32 bits of it, - * like the access through PTR_TO_ARENA is. The register stays a number. - */ -static bool is_arena_scalar(struct bpf_verifier_env *env, int regno) -{ - const struct bpf_reg_state *reg = reg_state(env, regno); - - return reg->type == SCALAR_VALUE && env->arena_scalar && env->prog->aux->arena; -} - static bool is_load_acq_unsafe(struct bpf_verifier_env *env, int regno, struct bpf_insn *insn) { @@ -5543,7 +5530,7 @@ static bool atomic_ptr_type_ok(struct bpf_verifier_env *env, int regno, return false; if (is_sk_reg(env, regno)) return false; - if (is_arena_reg(env, regno) || is_arena_scalar(env, regno)) + if (is_arena_reg(env, regno)) return bpf_jit_supports_insn(insn, true); if (is_load_acq_unsafe(env, regno, insn)) return false; @@ -7524,22 +7511,6 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, struct b static int save_aux_ptr_type(struct bpf_verifier_env *env, enum bpf_reg_type type, bool allow_trust_mismatch); -/* - * Returns the register to check the access of the current insn with. - * For a number in a program with an arena that is 'arena'. - */ -static struct bpf_reg_state *mem_access_reg(struct bpf_verifier_env *env, int regno, - struct bpf_reg_state *arena) -{ - if (!is_arena_scalar(env, regno)) - return cur_regs(env) + regno; - - memset(arena, 0, sizeof(*arena)); - arena->type = PTR_TO_ARENA; - env->insn_aux_data[env->insn_idx].arena_scalar = true; - return arena; -} - static int check_load_mem(struct bpf_verifier_env *env, struct bpf_insn *insn, bool strict_alignment_once, bool is_ldsx, bool allow_trust_mismatch, const char *ctx) @@ -7547,7 +7518,6 @@ static int check_load_mem(struct bpf_verifier_env *env, struct bpf_insn *insn, struct bpf_verifier_state *vstate = env->cur_state; struct bpf_func_state *state = vstate->frame[vstate->curframe]; struct bpf_reg_state *regs = cur_regs(env); - struct bpf_reg_state arena, *src_reg; enum bpf_reg_type src_reg_type; int err; @@ -7569,16 +7539,16 @@ static int check_load_mem(struct bpf_verifier_env *env, struct bpf_insn *insn, if (err) return err; - src_reg = mem_access_reg(env, insn->src_reg, &arena); - src_reg_type = src_reg->type; + src_reg_type = regs[insn->src_reg].type; /* * check_stack_read_fixed_off() may refine the modification's origin to * the source stack slot. */ bpf_diag_mod_begin(env, ®s[insn->dst_reg], NULL, BPF_DIAG_MOD_WRITE); - err = check_mem_access(env, env->insn_idx, src_reg, argno_from_reg(insn->src_reg), - insn->off, BPF_SIZE(insn->code), BPF_READ, insn->dst_reg, + err = check_mem_access(env, env->insn_idx, regs + insn->src_reg, + argno_from_reg(insn->src_reg), insn->off, + BPF_SIZE(insn->code), BPF_READ, insn->dst_reg, strict_alignment_once, is_ldsx); /* * Paths through a kernel struct pointer and through other pointers @@ -7606,7 +7576,6 @@ static int check_store_reg(struct bpf_verifier_env *env, struct bpf_insn *insn, struct bpf_verifier_state *vstate = env->cur_state; struct bpf_func_state *state = vstate->frame[vstate->curframe]; struct bpf_reg_state *regs = cur_regs(env); - struct bpf_reg_state arena, *dst_reg; enum bpf_reg_type dst_reg_type; int err; @@ -7628,12 +7597,12 @@ static int check_store_reg(struct bpf_verifier_env *env, struct bpf_insn *insn, if (err) return err; - dst_reg = mem_access_reg(env, insn->dst_reg, &arena); - dst_reg_type = dst_reg->type; + dst_reg_type = regs[insn->dst_reg].type; /* Check if (dst_reg + off) is writeable. */ - err = check_mem_access(env, env->insn_idx, dst_reg, argno_from_reg(insn->dst_reg), - insn->off, BPF_SIZE(insn->code), BPF_WRITE, insn->src_reg, + err = check_mem_access(env, env->insn_idx, regs + insn->dst_reg, + argno_from_reg(insn->dst_reg), insn->off, + BPF_SIZE(insn->code), BPF_WRITE, insn->src_reg, strict_alignment_once, false); err = err ?: save_aux_ptr_type(env, dst_reg_type, false); @@ -7643,7 +7612,7 @@ static int check_store_reg(struct bpf_verifier_env *env, struct bpf_insn *insn, static int check_atomic_rmw(struct bpf_verifier_env *env, struct bpf_insn *insn) { - struct bpf_reg_state arena, *dst_reg; + struct bpf_reg_state *dst_reg; int load_reg; int err; @@ -7688,9 +7657,6 @@ static int check_atomic_rmw(struct bpf_verifier_env *env, return -EACCES; } - /* load_reg may be dst_reg. Look at dst_reg before it's marked as unknown. */ - dst_reg = mem_access_reg(env, insn->dst_reg, &arena); - load_reg = bpf_atomic_load_reg(insn); if (load_reg >= 0) { /* check and record load of old value */ @@ -7699,6 +7665,8 @@ static int check_atomic_rmw(struct bpf_verifier_env *env, return err; } + dst_reg = cur_regs(env) + insn->dst_reg; + /* Check whether we can read the memory, with second call for fetch * case to simulate the register fill. */ @@ -20289,17 +20257,16 @@ static int do_check_insn(struct bpf_verifier_env *env, bool *do_print_state) return check_stack_arg_write(env, state, insn->off, NULL); } - struct bpf_reg_state arena, *dst_reg; enum bpf_reg_type dst_reg_type; err = check_reg_arg(env, insn->dst_reg, SRC_OP); if (err) return err; - dst_reg = mem_access_reg(env, insn->dst_reg, &arena); - dst_reg_type = dst_reg->type; + dst_reg_type = cur_regs(env)[insn->dst_reg].type; - err = check_mem_access(env, env->insn_idx, dst_reg, argno_from_reg(insn->dst_reg), + err = check_mem_access(env, env->insn_idx, cur_regs(env) + insn->dst_reg, + argno_from_reg(insn->dst_reg), insn->off, BPF_SIZE(insn->code), BPF_WRITE, -1, false, false); if (err) @@ -23935,7 +23902,6 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, if (is_priv) env->test_state_freq = attr->prog_flags & BPF_F_TEST_STATE_FREQ; env->test_reg_invariants = attr->prog_flags & BPF_F_TEST_REG_INVARIANTS; - env->arena_scalar = attr->prog_flags & BPF_F_ARENA_SCALAR; env->explored_states = kvzalloc_objs(struct list_head, state_htab_size(env), |
