Message ID | 20230409033431.3992432-3-joannelkoong@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | BPF |
Headers | show |
Series | Dynptr convenience helpers | expand |
On Sat, Apr 8, 2023 at 8:34 PM Joanne Koong <joannelkoong@gmail.com> wrote: > > bpf_dynptr_is_null returns true if the dynptr is null / invalid > (determined by whether ptr->data is NULL), else false if > the dynptr is a valid dynptr. > > bpf_dynptr_is_rdonly returns true if the dynptr is read-only, > else false if the dynptr is read-writable. > > Signed-off-by: Joanne Koong <joannelkoong@gmail.com> > --- > kernel/bpf/helpers.c | 23 +++++++++++++++++++---- > 1 file changed, 19 insertions(+), 4 deletions(-) > > diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c > index 51b4c4b5dbed..e4e84e92a4c6 100644 > --- a/kernel/bpf/helpers.c > +++ b/kernel/bpf/helpers.c > @@ -1423,7 +1423,7 @@ static const struct bpf_func_proto bpf_kptr_xchg_proto = { > #define DYNPTR_SIZE_MASK 0xFFFFFF > #define DYNPTR_RDONLY_BIT BIT(31) > > -static bool bpf_dynptr_is_rdonly(const struct bpf_dynptr_kern *ptr) > +static bool __bpf_dynptr_is_rdonly(const struct bpf_dynptr_kern *ptr) > { > return ptr->size & DYNPTR_RDONLY_BIT; > } > @@ -1570,7 +1570,7 @@ BPF_CALL_5(bpf_dynptr_write, const struct bpf_dynptr_kern *, dst, u32, offset, v > enum bpf_dynptr_type type; > int err; > > - if (!dst->data || bpf_dynptr_is_rdonly(dst)) > + if (!dst->data || __bpf_dynptr_is_rdonly(dst)) > return -EINVAL; > > err = bpf_dynptr_check_off_len(dst, offset, len); > @@ -1626,7 +1626,7 @@ BPF_CALL_3(bpf_dynptr_data, const struct bpf_dynptr_kern *, ptr, u32, offset, u3 > if (err) > return 0; > > - if (bpf_dynptr_is_rdonly(ptr)) > + if (__bpf_dynptr_is_rdonly(ptr)) > return 0; > > type = bpf_dynptr_get_type(ptr); > @@ -2254,7 +2254,7 @@ __bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr_kern *ptr, u32 offset > __bpf_kfunc void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr_kern *ptr, u32 offset, > void *buffer, u32 buffer__szk) > { > - if (!ptr->data || bpf_dynptr_is_rdonly(ptr)) > + if (!ptr->data || __bpf_dynptr_is_rdonly(ptr)) seems like all the uses of __bpf_dynptr_is_rdonly check !ptr->data explicitly, so maybe move that ptr->data check inside and simplify all the callers? Regardless, looks good: Acked-by: Andrii Nakryiko <andrii@kernel.org> > return NULL; > > /* bpf_dynptr_slice_rdwr is the same logic as bpf_dynptr_slice. > @@ -2322,6 +2322,19 @@ __bpf_kfunc int bpf_dynptr_trim(struct bpf_dynptr_kern *ptr, u32 len) > return bpf_dynptr_adjust(ptr, 0, len); > } > > +__bpf_kfunc bool bpf_dynptr_is_null(struct bpf_dynptr_kern *ptr) > +{ > + return !ptr->data; > +} > + > +__bpf_kfunc bool bpf_dynptr_is_rdonly(struct bpf_dynptr_kern *ptr) > +{ > + if (!ptr->data) > + return false; > + > + return __bpf_dynptr_is_rdonly(ptr); > +} > + > __bpf_kfunc void *bpf_cast_to_kern_ctx(void *obj) > { > return obj; > @@ -2396,6 +2409,8 @@ BTF_ID_FLAGS(func, bpf_iter_num_next, KF_ITER_NEXT | KF_RET_NULL) > BTF_ID_FLAGS(func, bpf_iter_num_destroy, KF_ITER_DESTROY) > BTF_ID_FLAGS(func, bpf_dynptr_trim) > BTF_ID_FLAGS(func, bpf_dynptr_advance) > +BTF_ID_FLAGS(func, bpf_dynptr_is_null) > +BTF_ID_FLAGS(func, bpf_dynptr_is_rdonly) > BTF_SET8_END(common_btf_ids) > > static const struct btf_kfunc_id_set common_kfunc_set = { > -- > 2.34.1 >
On Wed, Apr 12, 2023 at 2:50 PM Andrii Nakryiko <andrii.nakryiko@gmail.com> wrote: > > On Sat, Apr 8, 2023 at 8:34 PM Joanne Koong <joannelkoong@gmail.com> wrote: > > > > bpf_dynptr_is_null returns true if the dynptr is null / invalid > > (determined by whether ptr->data is NULL), else false if > > the dynptr is a valid dynptr. > > > > bpf_dynptr_is_rdonly returns true if the dynptr is read-only, > > else false if the dynptr is read-writable. > > > > Signed-off-by: Joanne Koong <joannelkoong@gmail.com> > > --- > > kernel/bpf/helpers.c | 23 +++++++++++++++++++---- > > 1 file changed, 19 insertions(+), 4 deletions(-) > > > > diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c > > index 51b4c4b5dbed..e4e84e92a4c6 100644 > > --- a/kernel/bpf/helpers.c > > +++ b/kernel/bpf/helpers.c > > @@ -1423,7 +1423,7 @@ static const struct bpf_func_proto bpf_kptr_xchg_proto = { > > #define DYNPTR_SIZE_MASK 0xFFFFFF > > #define DYNPTR_RDONLY_BIT BIT(31) > > > > -static bool bpf_dynptr_is_rdonly(const struct bpf_dynptr_kern *ptr) > > +static bool __bpf_dynptr_is_rdonly(const struct bpf_dynptr_kern *ptr) > > { > > return ptr->size & DYNPTR_RDONLY_BIT; > > } > > @@ -1570,7 +1570,7 @@ BPF_CALL_5(bpf_dynptr_write, const struct bpf_dynptr_kern *, dst, u32, offset, v > > enum bpf_dynptr_type type; > > int err; > > > > - if (!dst->data || bpf_dynptr_is_rdonly(dst)) > > + if (!dst->data || __bpf_dynptr_is_rdonly(dst)) > > return -EINVAL; > > > > err = bpf_dynptr_check_off_len(dst, offset, len); > > @@ -1626,7 +1626,7 @@ BPF_CALL_3(bpf_dynptr_data, const struct bpf_dynptr_kern *, ptr, u32, offset, u3 > > if (err) > > return 0; > > > > - if (bpf_dynptr_is_rdonly(ptr)) > > + if (__bpf_dynptr_is_rdonly(ptr)) > > return 0; > > > > type = bpf_dynptr_get_type(ptr); > > @@ -2254,7 +2254,7 @@ __bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr_kern *ptr, u32 offset > > __bpf_kfunc void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr_kern *ptr, u32 offset, > > void *buffer, u32 buffer__szk) > > { > > - if (!ptr->data || bpf_dynptr_is_rdonly(ptr)) > > + if (!ptr->data || __bpf_dynptr_is_rdonly(ptr)) > > seems like all the uses of __bpf_dynptr_is_rdonly check !ptr->data > explicitly, so maybe move that ptr->data check inside and simplify all > the callers? i think combining it gets confusing in the case where ptr->data is null, as to how the invoked places interpret the return value. I think having the check spelled out more explicitly in the invoked places (eg bpf_dynptr_write, bpf_dynptr_data, ...) makes it more clear as well where the check for null is happening. for v2 I will leave this as is, but also happy to change it if you prefer the two be combined > > Regardless, looks good: > > Acked-by: Andrii Nakryiko <andrii@kernel.org> > > > return NULL; > > > > /* bpf_dynptr_slice_rdwr is the same logic as bpf_dynptr_slice. > > @@ -2322,6 +2322,19 @@ __bpf_kfunc int bpf_dynptr_trim(struct bpf_dynptr_kern *ptr, u32 len) > > return bpf_dynptr_adjust(ptr, 0, len); > > } > > > > +__bpf_kfunc bool bpf_dynptr_is_null(struct bpf_dynptr_kern *ptr) > > +{ > > + return !ptr->data; > > +} > > + > > +__bpf_kfunc bool bpf_dynptr_is_rdonly(struct bpf_dynptr_kern *ptr) > > +{ > > + if (!ptr->data) > > + return false; > > + > > + return __bpf_dynptr_is_rdonly(ptr); > > +} > > + > > __bpf_kfunc void *bpf_cast_to_kern_ctx(void *obj) > > { > > return obj; > > @@ -2396,6 +2409,8 @@ BTF_ID_FLAGS(func, bpf_iter_num_next, KF_ITER_NEXT | KF_RET_NULL) > > BTF_ID_FLAGS(func, bpf_iter_num_destroy, KF_ITER_DESTROY) > > BTF_ID_FLAGS(func, bpf_dynptr_trim) > > BTF_ID_FLAGS(func, bpf_dynptr_advance) > > +BTF_ID_FLAGS(func, bpf_dynptr_is_null) > > +BTF_ID_FLAGS(func, bpf_dynptr_is_rdonly) > > BTF_SET8_END(common_btf_ids) > > > > static const struct btf_kfunc_id_set common_kfunc_set = { > > -- > > 2.34.1 > >
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 51b4c4b5dbed..e4e84e92a4c6 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -1423,7 +1423,7 @@ static const struct bpf_func_proto bpf_kptr_xchg_proto = { #define DYNPTR_SIZE_MASK 0xFFFFFF #define DYNPTR_RDONLY_BIT BIT(31) -static bool bpf_dynptr_is_rdonly(const struct bpf_dynptr_kern *ptr) +static bool __bpf_dynptr_is_rdonly(const struct bpf_dynptr_kern *ptr) { return ptr->size & DYNPTR_RDONLY_BIT; } @@ -1570,7 +1570,7 @@ BPF_CALL_5(bpf_dynptr_write, const struct bpf_dynptr_kern *, dst, u32, offset, v enum bpf_dynptr_type type; int err; - if (!dst->data || bpf_dynptr_is_rdonly(dst)) + if (!dst->data || __bpf_dynptr_is_rdonly(dst)) return -EINVAL; err = bpf_dynptr_check_off_len(dst, offset, len); @@ -1626,7 +1626,7 @@ BPF_CALL_3(bpf_dynptr_data, const struct bpf_dynptr_kern *, ptr, u32, offset, u3 if (err) return 0; - if (bpf_dynptr_is_rdonly(ptr)) + if (__bpf_dynptr_is_rdonly(ptr)) return 0; type = bpf_dynptr_get_type(ptr); @@ -2254,7 +2254,7 @@ __bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr_kern *ptr, u32 offset __bpf_kfunc void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr_kern *ptr, u32 offset, void *buffer, u32 buffer__szk) { - if (!ptr->data || bpf_dynptr_is_rdonly(ptr)) + if (!ptr->data || __bpf_dynptr_is_rdonly(ptr)) return NULL; /* bpf_dynptr_slice_rdwr is the same logic as bpf_dynptr_slice. @@ -2322,6 +2322,19 @@ __bpf_kfunc int bpf_dynptr_trim(struct bpf_dynptr_kern *ptr, u32 len) return bpf_dynptr_adjust(ptr, 0, len); } +__bpf_kfunc bool bpf_dynptr_is_null(struct bpf_dynptr_kern *ptr) +{ + return !ptr->data; +} + +__bpf_kfunc bool bpf_dynptr_is_rdonly(struct bpf_dynptr_kern *ptr) +{ + if (!ptr->data) + return false; + + return __bpf_dynptr_is_rdonly(ptr); +} + __bpf_kfunc void *bpf_cast_to_kern_ctx(void *obj) { return obj; @@ -2396,6 +2409,8 @@ BTF_ID_FLAGS(func, bpf_iter_num_next, KF_ITER_NEXT | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_iter_num_destroy, KF_ITER_DESTROY) BTF_ID_FLAGS(func, bpf_dynptr_trim) BTF_ID_FLAGS(func, bpf_dynptr_advance) +BTF_ID_FLAGS(func, bpf_dynptr_is_null) +BTF_ID_FLAGS(func, bpf_dynptr_is_rdonly) BTF_SET8_END(common_btf_ids) static const struct btf_kfunc_id_set common_kfunc_set = {
bpf_dynptr_is_null returns true if the dynptr is null / invalid (determined by whether ptr->data is NULL), else false if the dynptr is a valid dynptr. bpf_dynptr_is_rdonly returns true if the dynptr is read-only, else false if the dynptr is read-writable. Signed-off-by: Joanne Koong <joannelkoong@gmail.com> --- kernel/bpf/helpers.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)