bpf: generalize dynptr_get_spi to be usable for iters
Generalize the logic of fetching special stack slot object state using spi (stack slot index). This will be used by STACK_ITER logic next. Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/r/20230302235015.2044271-12-andrii@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
d5271c5b19
commit
a461f5adf1
@ -710,32 +710,38 @@ static bool is_spi_bounds_valid(struct bpf_func_state *state, int spi, int nr_sl
|
||||
return spi - nr_slots + 1 >= 0 && spi < allocated_slots;
|
||||
}
|
||||
|
||||
static int dynptr_get_spi(struct bpf_verifier_env *env, struct bpf_reg_state *reg)
|
||||
static int stack_slot_obj_get_spi(struct bpf_verifier_env *env, struct bpf_reg_state *reg,
|
||||
const char *obj_kind, int nr_slots)
|
||||
{
|
||||
int off, spi;
|
||||
|
||||
if (!tnum_is_const(reg->var_off)) {
|
||||
verbose(env, "dynptr has to be at a constant offset\n");
|
||||
verbose(env, "%s has to be at a constant offset\n", obj_kind);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
off = reg->off + reg->var_off.value;
|
||||
if (off % BPF_REG_SIZE) {
|
||||
verbose(env, "cannot pass in dynptr at an offset=%d\n", off);
|
||||
verbose(env, "cannot pass in %s at an offset=%d\n", obj_kind, off);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
spi = __get_spi(off);
|
||||
if (spi < 1) {
|
||||
verbose(env, "cannot pass in dynptr at an offset=%d\n", off);
|
||||
if (spi + 1 < nr_slots) {
|
||||
verbose(env, "cannot pass in %s at an offset=%d\n", obj_kind, off);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!is_spi_bounds_valid(func(env, reg), spi, BPF_DYNPTR_NR_SLOTS))
|
||||
if (!is_spi_bounds_valid(func(env, reg), spi, nr_slots))
|
||||
return -ERANGE;
|
||||
return spi;
|
||||
}
|
||||
|
||||
static int dynptr_get_spi(struct bpf_verifier_env *env, struct bpf_reg_state *reg)
|
||||
{
|
||||
return stack_slot_obj_get_spi(env, reg, "dynptr", BPF_DYNPTR_NR_SLOTS);
|
||||
}
|
||||
|
||||
static const char *kernel_type_name(const struct btf* btf, u32 id)
|
||||
{
|
||||
return btf_name_by_offset(btf, btf_type_by_id(btf, id)->name_off);
|
||||
|
Loading…
x
Reference in New Issue
Block a user