On Mon, May 9, 2022 at 3:44 PM Joanne Koong <joannelkoong@xxxxxxxxx> wrote: > > This patch adds a new helper function > > void *bpf_dynptr_data(struct bpf_dynptr *ptr, u32 offset, u32 len); > > which returns a pointer to the underlying data of a dynptr. *len* > must be a statically known value. The bpf program may access the returned > data slice as a normal buffer (eg can do direct reads and writes), since > the verifier associates the length with the returned pointer, and > enforces that no out of bounds accesses occur. > > Signed-off-by: Joanne Koong <joannelkoong@xxxxxxxxx> > --- Minor nit below. Acked-by: Andrii Nakryiko <andrii@xxxxxxxxxx> > include/linux/bpf.h | 4 ++ > include/uapi/linux/bpf.h | 12 ++++++ > kernel/bpf/helpers.c | 28 ++++++++++++++ > kernel/bpf/verifier.c | 67 +++++++++++++++++++++++++++++++--- > tools/include/uapi/linux/bpf.h | 12 ++++++ > 5 files changed, 117 insertions(+), 6 deletions(-) > [...] > @@ -797,6 +806,20 @@ static bool is_dynptr_reg_valid_init(struct bpf_verifier_env *env, struct bpf_re > return state->stack[spi].spilled_ptr.dynptr.type == arg_to_dynptr_type(arg_type); > } > > +static bool is_ref_obj_id_dynptr(struct bpf_func_state *state, u32 id) > +{ > + int allocated_slots = state->allocated_stack / BPF_REG_SIZE; > + int i; > + > + for (i = 0; i < allocated_slots; i++) { > + if (state->stack[i].slot_type[0] == STACK_DYNPTR && > + state->stack[i].spilled_ptr.id == id) > + return true; there is probably no harm, but strictly speaking we should check only stack slot that corresponds to the start of dynptr, right? > + } > + > + return false; > +} > + > /* The reg state of a pointer or a bounded scalar was saved when > * it was spilled to the stack. > */ [...]