rcuscale: Move shutdown from wait_event() to wait_event_idle()
[platform/kernel/linux-starfive.git] / kernel / bpf / verifier.c
index 264b3dc..49c6b5e 100644 (file)
@@ -1000,6 +1000,8 @@ static void print_insn_state(struct bpf_verifier_env *env,
  */
 static void *copy_array(void *dst, const void *src, size_t n, size_t size, gfp_t flags)
 {
+       size_t alloc_bytes;
+       void *orig = dst;
        size_t bytes;
 
        if (ZERO_OR_NULL_PTR(src))
@@ -1008,11 +1010,11 @@ static void *copy_array(void *dst, const void *src, size_t n, size_t size, gfp_t
        if (unlikely(check_mul_overflow(n, size, &bytes)))
                return NULL;
 
-       if (ksize(dst) < bytes) {
-               kfree(dst);
-               dst = kmalloc_track_caller(bytes, flags);
-               if (!dst)
-                       return NULL;
+       alloc_bytes = max(ksize(orig), kmalloc_size_roundup(bytes));
+       dst = krealloc(orig, alloc_bytes, flags);
+       if (!dst) {
+               kfree(orig);
+               return NULL;
        }
 
        memcpy(dst, src, bytes);
@@ -1027,12 +1029,14 @@ out:
  */
 static void *realloc_array(void *arr, size_t old_n, size_t new_n, size_t size)
 {
+       size_t alloc_size;
        void *new_arr;
 
        if (!new_n || old_n == new_n)
                goto out;
 
-       new_arr = krealloc_array(arr, new_n, size, GFP_KERNEL);
+       alloc_size = kmalloc_size_roundup(size_mul(new_n, size));
+       new_arr = krealloc(arr, alloc_size, GFP_KERNEL);
        if (!new_arr) {
                kfree(arr);
                return NULL;
@@ -1586,9 +1590,9 @@ static void __reg_bound_offset(struct bpf_reg_state *reg)
        struct tnum var64_off = tnum_intersect(reg->var_off,
                                               tnum_range(reg->umin_value,
                                                          reg->umax_value));
-       struct tnum var32_off = tnum_intersect(tnum_subreg(reg->var_off),
-                                               tnum_range(reg->u32_min_value,
-                                                          reg->u32_max_value));
+       struct tnum var32_off = tnum_intersect(tnum_subreg(var64_off),
+                                              tnum_range(reg->u32_min_value,
+                                                         reg->u32_max_value));
 
        reg->var_off = tnum_or(tnum_clear_subreg(var64_off), var32_off);
 }
@@ -2504,9 +2508,11 @@ static int push_jmp_history(struct bpf_verifier_env *env,
 {
        u32 cnt = cur->jmp_history_cnt;
        struct bpf_idx_pair *p;
+       size_t alloc_size;
 
        cnt++;
-       p = krealloc(cur->jmp_history, cnt * sizeof(*p), GFP_USER);
+       alloc_size = kmalloc_size_roundup(size_mul(cnt, sizeof(*p)));
+       p = krealloc(cur->jmp_history, alloc_size, GFP_USER);
        if (!p)
                return -ENOMEM;
        p[cnt - 1].idx = env->insn_idx;
@@ -2658,6 +2664,12 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
                if (opcode == BPF_CALL) {
                        if (insn->src_reg == BPF_PSEUDO_CALL)
                                return -ENOTSUPP;
+                       /* kfunc with imm==0 is invalid and fixup_kfunc_call will
+                        * catch this error later. Make backtracking conservative
+                        * with ENOTSUPP.
+                        */
+                       if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL && insn->imm == 0)
+                               return -ENOTSUPP;
                        /* regular helper call sets R0 */
                        *reg_mask &= ~1;
                        if (*reg_mask & 0x3f) {
@@ -2670,6 +2682,21 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx,
                        }
                } else if (opcode == BPF_EXIT) {
                        return -ENOTSUPP;
+               } else if (BPF_SRC(insn->code) == BPF_X) {
+                       if (!(*reg_mask & (dreg | sreg)))
+                               return 0;
+                       /* dreg <cond> sreg
+                        * Both dreg and sreg need precision before
+                        * this insn. If only sreg was marked precise
+                        * before it would be equally necessary to
+                        * propagate it to dreg.
+                        */
+                       *reg_mask |= (sreg | dreg);
+                        /* else dreg <cond> K
+                         * Only dreg still needs precision before
+                         * this insn, so for the K-based conditional
+                         * there is nothing new to be marked.
+                         */
                }
        } else if (class == BPF_LD) {
                if (!(*reg_mask & dreg))
@@ -2768,7 +2795,7 @@ static void mark_all_scalars_precise(struct bpf_verifier_env *env,
                }
 }
 
-static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
+static int __mark_chain_precision(struct bpf_verifier_env *env, int frame, int regno,
                                  int spi)
 {
        struct bpf_verifier_state *st = env->cur_state;
@@ -2785,7 +2812,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
        if (!env->bpf_capable)
                return 0;
 
-       func = st->frame[st->curframe];
+       func = st->frame[frame];
        if (regno >= 0) {
                reg = &func->regs[regno];
                if (reg->type != SCALAR_VALUE) {
@@ -2866,7 +2893,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
                        break;
 
                new_marks = false;
-               func = st->frame[st->curframe];
+               func = st->frame[frame];
                bitmap_from_u64(mask, reg_mask);
                for_each_set_bit(i, mask, 32) {
                        reg = &func->regs[i];
@@ -2932,12 +2959,17 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
 
 int mark_chain_precision(struct bpf_verifier_env *env, int regno)
 {
-       return __mark_chain_precision(env, regno, -1);
+       return __mark_chain_precision(env, env->cur_state->curframe, regno, -1);
+}
+
+static int mark_chain_precision_frame(struct bpf_verifier_env *env, int frame, int regno)
+{
+       return __mark_chain_precision(env, frame, regno, -1);
 }
 
-static int mark_chain_precision_stack(struct bpf_verifier_env *env, int spi)
+static int mark_chain_precision_stack_frame(struct bpf_verifier_env *env, int frame, int spi)
 {
-       return __mark_chain_precision(env, -1, spi);
+       return __mark_chain_precision(env, frame, -1, spi);
 }
 
 static bool is_spillable_regtype(enum bpf_reg_type type)
@@ -3000,13 +3032,24 @@ static bool __is_pointer_value(bool allow_ptr_leaks,
        return reg->type != SCALAR_VALUE;
 }
 
+/* Copy src state preserving dst->parent and dst->live fields */
+static void copy_register_state(struct bpf_reg_state *dst, const struct bpf_reg_state *src)
+{
+       struct bpf_reg_state *parent = dst->parent;
+       enum bpf_reg_liveness live = dst->live;
+
+       *dst = *src;
+       dst->parent = parent;
+       dst->live = live;
+}
+
 static void save_register_state(struct bpf_func_state *state,
                                int spi, struct bpf_reg_state *reg,
                                int size)
 {
        int i;
 
-       state->stack[spi].spilled_ptr = *reg;
+       copy_register_state(&state->stack[spi].spilled_ptr, reg);
        if (size == BPF_REG_SIZE)
                state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN;
 
@@ -3018,6 +3061,11 @@ static void save_register_state(struct bpf_func_state *state,
                scrub_spilled_slot(&state->stack[spi].slot_type[i - 1]);
 }
 
+static bool is_bpf_st_mem(struct bpf_insn *insn)
+{
+       return BPF_CLASS(insn->code) == BPF_ST && BPF_MODE(insn->code) == BPF_MEM;
+}
+
 /* check_stack_{read,write}_fixed_off functions track spill/fill of registers,
  * stack boundary and alignment are checked in check_mem_access()
  */
@@ -3029,8 +3077,9 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
 {
        struct bpf_func_state *cur; /* state of the current function */
        int i, slot = -off - 1, spi = slot / BPF_REG_SIZE, err;
-       u32 dst_reg = env->prog->insnsi[insn_idx].dst_reg;
+       struct bpf_insn *insn = &env->prog->insnsi[insn_idx];
        struct bpf_reg_state *reg = NULL;
+       u32 dst_reg = insn->dst_reg;
 
        err = grow_stack_state(state, round_up(slot + 1, BPF_REG_SIZE));
        if (err)
@@ -3052,7 +3101,9 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
                bool sanitize = reg && is_spillable_regtype(reg->type);
 
                for (i = 0; i < size; i++) {
-                       if (state->stack[spi].slot_type[i] == STACK_INVALID) {
+                       u8 type = state->stack[spi].slot_type[i];
+
+                       if (type != STACK_MISC && type != STACK_ZERO) {
                                sanitize = true;
                                break;
                        }
@@ -3077,6 +3128,16 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
                                return err;
                }
                save_register_state(state, spi, reg, size);
+               /* Break the relation on a narrowing spill. */
+               if (fls64(reg->umax_value) > BITS_PER_BYTE * size)
+                       state->stack[spi].spilled_ptr.id = 0;
+       } else if (!reg && !(off % BPF_REG_SIZE) && is_bpf_st_mem(insn) &&
+                  insn->imm != 0 && env->bpf_capable) {
+               struct bpf_reg_state fake_reg = {};
+
+               __mark_reg_known(&fake_reg, (u32)insn->imm);
+               fake_reg.type = SCALAR_VALUE;
+               save_register_state(state, spi, &fake_reg, size);
        } else if (reg && is_spillable_regtype(reg->type)) {
                /* register containing pointer is being spilled into stack */
                if (size != BPF_REG_SIZE) {
@@ -3111,7 +3172,8 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
                        state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN;
 
                /* when we zero initialize stack slots mark them as such */
-               if (reg && register_is_null(reg)) {
+               if ((reg && register_is_null(reg)) ||
+                   (!reg && is_bpf_st_mem(insn) && insn->imm == 0)) {
                        /* backtracking doesn't work for STACK_ZERO yet. */
                        err = mark_chain_precision(env, value_regno);
                        if (err)
@@ -3186,14 +3248,17 @@ static int check_stack_write_var_off(struct bpf_verifier_env *env,
                stype = &state->stack[spi].slot_type[slot % BPF_REG_SIZE];
                mark_stack_slot_scratched(env, spi);
 
-               if (!env->allow_ptr_leaks
-                               && *stype != NOT_INIT
-                               && *stype != SCALAR_VALUE) {
-                       /* Reject the write if there's are spilled pointers in
-                        * range. If we didn't reject here, the ptr status
-                        * would be erased below (even though not all slots are
-                        * actually overwritten), possibly opening the door to
-                        * leaks.
+               if (!env->allow_ptr_leaks && *stype != STACK_MISC && *stype != STACK_ZERO) {
+                       /* Reject the write if range we may write to has not
+                        * been initialized beforehand. If we didn't reject
+                        * here, the ptr status would be erased below (even
+                        * though not all slots are actually overwritten),
+                        * possibly opening the door to leaks.
+                        *
+                        * We do however catch STACK_INVALID case below, and
+                        * only allow reading possibly uninitialized memory
+                        * later for CAP_PERFMON, as the write may not happen to
+                        * that slot.
                         */
                        verbose(env, "spilled ptr in range of var-offset stack write; insn %d, ptr off: %d",
                                insn_idx, i);
@@ -3329,7 +3394,7 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
                                 */
                                s32 subreg_def = state->regs[dst_regno].subreg_def;
 
-                               state->regs[dst_regno] = *reg;
+                               copy_register_state(&state->regs[dst_regno], reg);
                                state->regs[dst_regno].subreg_def = subreg_def;
                        } else {
                                for (i = 0; i < size; i++) {
@@ -3350,7 +3415,7 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
 
                if (dst_regno >= 0) {
                        /* restore register state from stack */
-                       state->regs[dst_regno] = *reg;
+                       copy_register_state(&state->regs[dst_regno], reg);
                        /* mark reg as written since spilled pointer state likely
                         * has its liveness marks cleared by is_state_visited()
                         * which resets stack/reg liveness for state transitions
@@ -3470,17 +3535,13 @@ static int check_stack_read(struct bpf_verifier_env *env,
        }
        /* Variable offset is prohibited for unprivileged mode for simplicity
         * since it requires corresponding support in Spectre masking for stack
-        * ALU. See also retrieve_ptr_limit().
+        * ALU. See also retrieve_ptr_limit(). The check in
+        * check_stack_access_for_ptr_arithmetic() called by
+        * adjust_ptr_min_max_vals() prevents users from creating stack pointers
+        * with variable offsets, therefore no check is required here. Further,
+        * just checking it here would be insufficient as speculative stack
+        * writes could still lead to unsafe speculative behaviour.
         */
-       if (!env->bypass_spec_v1 && var_off) {
-               char tn_buf[48];
-
-               tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
-               verbose(env, "R%d variable offset stack access prohibited for !root, var_off=%s\n",
-                               ptr_regno, tn_buf);
-               return -EACCES;
-       }
-
        if (!var_off) {
                off += reg->var_off.value;
                err = check_stack_read_fixed_off(env, state, off, size,
@@ -5160,10 +5221,6 @@ static int check_stack_range_initialized(
                }
 
                if (is_spilled_reg(&state->stack[spi]) &&
-                   base_type(state->stack[spi].spilled_ptr.type) == PTR_TO_BTF_ID)
-                       goto mark;
-
-               if (is_spilled_reg(&state->stack[spi]) &&
                    (state->stack[spi].spilled_ptr.type == SCALAR_VALUE ||
                     env->allow_ptr_leaks)) {
                        if (clobber) {
@@ -5193,6 +5250,11 @@ mark:
                mark_reg_read(env, &state->stack[spi].spilled_ptr,
                              state->stack[spi].spilled_ptr.parent,
                              REG_LIVE_READ64);
+               /* We do not set REG_LIVE_WRITTEN for stack slot, as we can not
+                * be sure that whether stack slot is written to or not. Hence,
+                * we must still conservatively propagate reads upwards even if
+                * helper may write to the entire memory range.
+                */
        }
        return update_stack_depth(env, state, min_off);
 }
@@ -8068,7 +8130,7 @@ do_sim:
         */
        if (!ptr_is_dst_reg) {
                tmp = *dst_reg;
-               *dst_reg = *ptr_reg;
+               copy_register_state(dst_reg, ptr_reg);
        }
        ret = sanitize_speculative_path(env, NULL, env->insn_idx + 1,
                                        env->insn_idx);
@@ -9211,6 +9273,11 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
                                return err;
                        return adjust_ptr_min_max_vals(env, insn,
                                                       dst_reg, src_reg);
+               } else if (dst_reg->precise) {
+                       /* if dst_reg is precise, src_reg should be precise as well */
+                       err = mark_chain_precision(env, insn->src_reg);
+                       if (err)
+                               return err;
                }
        } else {
                /* Pretend the src is a reg with a known value, since we only
@@ -9316,7 +9383,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
                                         * to propagate min/max range.
                                         */
                                        src_reg->id = ++env->id_gen;
-                               *dst_reg = *src_reg;
+                               copy_register_state(dst_reg, src_reg);
                                dst_reg->live |= REG_LIVE_WRITTEN;
                                dst_reg->subreg_def = DEF_NOT_SUBREG;
                        } else {
@@ -9327,7 +9394,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
                                                insn->src_reg);
                                        return -EACCES;
                                } else if (src_reg->type == SCALAR_VALUE) {
-                                       *dst_reg = *src_reg;
+                                       copy_register_state(dst_reg, src_reg);
                                        /* Make sure ID is cleared otherwise
                                         * dst_reg min/max could be incorrectly
                                         * propagated into src_reg by find_equal_scalars()
@@ -10123,7 +10190,7 @@ static void find_equal_scalars(struct bpf_verifier_state *vstate,
 
        bpf_for_each_reg_in_vstate(vstate, state, reg, ({
                if (reg->type == SCALAR_VALUE && reg->id == known_reg->id)
-                       *reg = *known_reg;
+                       copy_register_state(reg, known_reg);
        }));
 }
 
@@ -11847,34 +11914,38 @@ static int propagate_precision(struct bpf_verifier_env *env,
 {
        struct bpf_reg_state *state_reg;
        struct bpf_func_state *state;
-       int i, err = 0;
+       int i, err = 0, fr;
 
-       state = old->frame[old->curframe];
-       state_reg = state->regs;
-       for (i = 0; i < BPF_REG_FP; i++, state_reg++) {
-               if (state_reg->type != SCALAR_VALUE ||
-                   !state_reg->precise)
-                       continue;
-               if (env->log.level & BPF_LOG_LEVEL2)
-                       verbose(env, "propagating r%d\n", i);
-               err = mark_chain_precision(env, i);
-               if (err < 0)
-                       return err;
-       }
+       for (fr = old->curframe; fr >= 0; fr--) {
+               state = old->frame[fr];
+               state_reg = state->regs;
+               for (i = 0; i < BPF_REG_FP; i++, state_reg++) {
+                       if (state_reg->type != SCALAR_VALUE ||
+                           !state_reg->precise ||
+                           !(state_reg->live & REG_LIVE_READ))
+                               continue;
+                       if (env->log.level & BPF_LOG_LEVEL2)
+                               verbose(env, "frame %d: propagating r%d\n", fr, i);
+                       err = mark_chain_precision_frame(env, fr, i);
+                       if (err < 0)
+                               return err;
+               }
 
-       for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) {
-               if (!is_spilled_reg(&state->stack[i]))
-                       continue;
-               state_reg = &state->stack[i].spilled_ptr;
-               if (state_reg->type != SCALAR_VALUE ||
-                   !state_reg->precise)
-                       continue;
-               if (env->log.level & BPF_LOG_LEVEL2)
-                       verbose(env, "propagating fp%d\n",
-                               (-i - 1) * BPF_REG_SIZE);
-               err = mark_chain_precision_stack(env, i);
-               if (err < 0)
-                       return err;
+               for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) {
+                       if (!is_spilled_reg(&state->stack[i]))
+                               continue;
+                       state_reg = &state->stack[i].spilled_ptr;
+                       if (state_reg->type != SCALAR_VALUE ||
+                           !state_reg->precise ||
+                           !(state_reg->live & REG_LIVE_READ))
+                               continue;
+                       if (env->log.level & BPF_LOG_LEVEL2)
+                               verbose(env, "frame %d: propagating fp%d\n",
+                                       fr, (-i - 1) * BPF_REG_SIZE);
+                       err = mark_chain_precision_stack_frame(env, fr, i);
+                       if (err < 0)
+                               return err;
+               }
        }
        return 0;
 }
@@ -13386,6 +13457,10 @@ static int opt_subreg_zext_lo32_rnd_hi32(struct bpf_verifier_env *env,
                if (!bpf_jit_needs_zext() && !is_cmpxchg_insn(&insn))
                        continue;
 
+               /* Zero-extension is done by the caller. */
+               if (bpf_pseudo_kfunc_call(&insn))
+                       continue;
+
                if (WARN_ON(load_reg == -1)) {
                        verbose(env, "verifier bug. zext_dst is set, but no reg is defined\n");
                        return -EFAULT;
@@ -13580,7 +13655,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
                                        insn_buf[cnt++] = BPF_ALU64_IMM(BPF_RSH,
                                                                        insn->dst_reg,
                                                                        shift);
-                               insn_buf[cnt++] = BPF_ALU64_IMM(BPF_AND, insn->dst_reg,
+                               insn_buf[cnt++] = BPF_ALU32_IMM(BPF_AND, insn->dst_reg,
                                                                (1ULL << size * 8) - 1);
                        }
                }
@@ -13761,9 +13836,10 @@ static int jit_subprogs(struct bpf_verifier_env *env)
        }
 
        /* finally lock prog and jit images for all functions and
-        * populate kallsysm
+        * populate kallsysm. Begin at the first subprogram, since
+        * bpf_prog_load will add the kallsyms for the main program.
         */
-       for (i = 0; i < env->subprog_cnt; i++) {
+       for (i = 1; i < env->subprog_cnt; i++) {
                bpf_prog_lock_ro(func[i]);
                bpf_prog_kallsyms_add(func[i]);
        }
@@ -13789,6 +13865,8 @@ static int jit_subprogs(struct bpf_verifier_env *env)
        prog->jited = 1;
        prog->bpf_func = func[0]->bpf_func;
        prog->jited_len = func[0]->jited_len;
+       prog->aux->extable = func[0]->aux->extable;
+       prog->aux->num_exentries = func[0]->aux->num_exentries;
        prog->aux->func = func;
        prog->aux->func_cnt = env->subprog_cnt;
        bpf_prog_jit_attempt_done(prog);
@@ -15075,6 +15153,10 @@ BTF_ID(func, migrate_enable)
 #if !defined CONFIG_PREEMPT_RCU && !defined CONFIG_TINY_RCU
 BTF_ID(func, rcu_read_unlock_strict)
 #endif
+#if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_TRACE_PREEMPT_TOGGLE)
+BTF_ID(func, preempt_count_add)
+BTF_ID(func, preempt_count_sub)
+#endif
 BTF_SET_END(btf_id_deny)
 
 static int check_attach_btf_id(struct bpf_verifier_env *env)