The task of calculating bpf_dynptr_kern's available size, and the current (offset) data pointer is common for BPF functions working with ARG_PTR_TO_DYNPTR parameters. Introduce 'bpf_dynptr_get_data' which returns the current data (with properer offset), and the number of usable bytes it has. This will void callers from directly calculating bpf_dynptr_kern's data, offset and size. Signed-off-by: Shmulik Ladkani <shmulik.ladkani@xxxxxxxxx> --- include/linux/bpf.h | 1 + kernel/bpf/helpers.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 39bd36359c1e..6d288dfc302b 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -2576,6 +2576,7 @@ void bpf_dynptr_init(struct bpf_dynptr_kern *ptr, void *data, enum bpf_dynptr_type type, u32 offset, u32 size); void bpf_dynptr_set_null(struct bpf_dynptr_kern *ptr); int bpf_dynptr_check_size(u32 size); +void *bpf_dynptr_get_data(struct bpf_dynptr_kern *ptr, u32 *avail_bytes); #ifdef CONFIG_BPF_LSM void bpf_cgroup_atype_get(u32 attach_btf_id, int cgroup_atype); diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 3c1b9bbcf971..91f406a9c37f 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -1461,6 +1461,16 @@ void bpf_dynptr_init(struct bpf_dynptr_kern *ptr, void *data, bpf_dynptr_set_type(ptr, type); } +void *bpf_dynptr_get_data(struct bpf_dynptr_kern *ptr, u32 *avail_bytes) +{ + u32 size = bpf_dynptr_get_size(ptr); + + if (!ptr->data || ptr->offset > size) + return NULL; + *avail_bytes = size - ptr->offset; + return ptr->data + ptr->offset; +} + void bpf_dynptr_set_null(struct bpf_dynptr_kern *ptr) { memset(ptr, 0, sizeof(*ptr)); -- 2.37.2