From: David Vernet <void@manifault.com>
To: Joanne Koong <joannelkoong@gmail.com>
Cc: bpf@vger.kernel.org, andrii@kernel.org, ast@kernel.org,
daniel@iogearbox.net
Subject: Re: [PATCH bpf-next v4 4/6] bpf: Add bpf_dynptr_read and bpf_dynptr_write
Date: Mon, 16 May 2022 09:56:27 -0700 [thread overview]
Message-ID: <20220516165627.4a2kdpgzmln5ejew@dev0025.ash9.facebook.com> (raw)
In-Reply-To: <20220509224257.3222614-5-joannelkoong@gmail.com>
On Mon, May 09, 2022 at 03:42:55PM -0700, Joanne Koong wrote:
> This patch adds two helper functions, bpf_dynptr_read and
> bpf_dynptr_write:
>
> long bpf_dynptr_read(void *dst, u32 len, struct bpf_dynptr *src, u32 offset);
>
> long bpf_dynptr_write(struct bpf_dynptr *dst, u32 offset, void *src, u32 len);
>
> The dynptr passed into these functions must be valid dynptrs that have
> been initialized.
>
> Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
> ---
> include/linux/bpf.h | 16 ++++++++++
> include/uapi/linux/bpf.h | 19 ++++++++++++
> kernel/bpf/helpers.c | 56 ++++++++++++++++++++++++++++++++++
> tools/include/uapi/linux/bpf.h | 19 ++++++++++++
> 4 files changed, 110 insertions(+)
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 8fbe739b0dec..6f4fa0627620 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -2391,6 +2391,12 @@ enum bpf_dynptr_type {
> #define DYNPTR_SIZE_MASK 0xFFFFFF
> #define DYNPTR_TYPE_SHIFT 28
> #define DYNPTR_TYPE_MASK 0x7
> +#define DYNPTR_RDONLY_BIT BIT(31)
> +
> +static inline bool bpf_dynptr_is_rdonly(struct bpf_dynptr_kern *ptr)
> +{
> + return ptr->size & DYNPTR_RDONLY_BIT;
> +}
>
> static inline enum bpf_dynptr_type bpf_dynptr_get_type(struct bpf_dynptr_kern *ptr)
> {
> @@ -2412,6 +2418,16 @@ static inline int bpf_dynptr_check_size(u32 size)
> return size > DYNPTR_MAX_SIZE ? -E2BIG : 0;
> }
>
> +static inline int bpf_dynptr_check_off_len(struct bpf_dynptr_kern *ptr, u32 offset, u32 len)
> +{
> + u32 size = bpf_dynptr_get_size(ptr);
> +
> + if (len > size || offset > size - len)
> + return -E2BIG;
> +
> + return 0;
> +}
Does this need to be in bpf.h? Or could it be brought into helpers.c as a
static function? I don't think there's any harm in leaving it here, but at
first glance it seems like a helper function that doesn't really need to be
exported.
> +
> void bpf_dynptr_init(struct bpf_dynptr_kern *ptr, void *data, enum bpf_dynptr_type type,
> u32 offset, u32 size);
>
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 679f960d2514..f0c5ca220d8e 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -5209,6 +5209,23 @@ union bpf_attr {
> * 'bpf_ringbuf_discard'.
> * Return
> * Nothing. Always succeeds.
> + *
> + * long bpf_dynptr_read(void *dst, u32 len, struct bpf_dynptr *src, u32 offset)
> + * Description
> + * Read *len* bytes from *src* into *dst*, starting from *offset*
> + * into *src*.
> + * Return
> + * 0 on success, -E2BIG if *offset* + *len* exceeds the length
> + * of *src*'s data, -EINVAL if *src* is an invalid dynptr.
> + *
> + * long bpf_dynptr_write(struct bpf_dynptr *dst, u32 offset, void *src, u32 len)
> + * Description
> + * Write *len* bytes from *src* into *dst*, starting from *offset*
> + * into *dst*.
> + * Return
> + * 0 on success, -E2BIG if *offset* + *len* exceeds the length
> + * of *dst*'s data, -EINVAL if *dst* is an invalid dynptr or if *dst*
> + * is a read-only dynptr.
> */
> #define __BPF_FUNC_MAPPER(FN) \
> FN(unspec), \
> @@ -5411,6 +5428,8 @@ union bpf_attr {
> FN(ringbuf_reserve_dynptr), \
> FN(ringbuf_submit_dynptr), \
> FN(ringbuf_discard_dynptr), \
> + FN(dynptr_read), \
> + FN(dynptr_write), \
> /* */
>
> /* integer value in 'imm' field of BPF_CALL instruction selects which helper
> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
> index 2d6f2e28b580..7206b9e5322f 100644
> --- a/kernel/bpf/helpers.c
> +++ b/kernel/bpf/helpers.c
> @@ -1467,6 +1467,58 @@ const struct bpf_func_proto bpf_dynptr_put_proto = {
> .arg1_type = ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_MALLOC | OBJ_RELEASE,
> };
>
> +BPF_CALL_4(bpf_dynptr_read, void *, dst, u32, len, struct bpf_dynptr_kern *, src, u32, offset)
> +{
> + int err;
> +
> + if (!src->data)
> + return -EINVAL;
> +
> + err = bpf_dynptr_check_off_len(src, offset, len);
> + if (err)
> + return err;
> +
> + memcpy(dst, src->data + src->offset + offset, len);
> +
> + return 0;
> +}
> +
> +const struct bpf_func_proto bpf_dynptr_read_proto = {
> + .func = bpf_dynptr_read,
> + .gpl_only = false,
> + .ret_type = RET_INTEGER,
> + .arg1_type = ARG_PTR_TO_UNINIT_MEM,
> + .arg2_type = ARG_CONST_SIZE_OR_ZERO,
> + .arg3_type = ARG_PTR_TO_DYNPTR,
> + .arg4_type = ARG_ANYTHING,
I think what you have now is safe / correct, but is there a reason that we
don't use ARG_CONST_SIZE_OR_ZERO for both the len and the offset, given
that they're both bound by the size of a memory region? Same question
applies to the function proto for bpf_dynptr_write() as well.
> +};
> +
> +BPF_CALL_4(bpf_dynptr_write, struct bpf_dynptr_kern *, dst, u32, offset, void *, src, u32, len)
> +{
> + int err;
> +
> + if (!dst->data || bpf_dynptr_is_rdonly(dst))
> + return -EINVAL;
> +
> + err = bpf_dynptr_check_off_len(dst, offset, len);
> + if (err)
> + return err;
> +
> + memcpy(dst->data + dst->offset + offset, src, len);
> +
> + return 0;
> +}
> +
> +const struct bpf_func_proto bpf_dynptr_write_proto = {
> + .func = bpf_dynptr_write,
> + .gpl_only = false,
> + .ret_type = RET_INTEGER,
> + .arg1_type = ARG_PTR_TO_DYNPTR,
> + .arg2_type = ARG_ANYTHING,
> + .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY,
> + .arg4_type = ARG_CONST_SIZE_OR_ZERO,
> +};
> +
[...]
Overall looks great.
next prev parent reply other threads:[~2022-05-16 16:58 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-09 22:42 [PATCH bpf-next v4 0/6] Dynamic pointers Joanne Koong
2022-05-09 22:42 ` [PATCH bpf-next v4 1/6] bpf: Add MEM_UNINIT as a bpf_type_flag Joanne Koong
2022-05-13 14:11 ` David Vernet
2022-05-09 22:42 ` [PATCH bpf-next v4 2/6] bpf: Add verifier support for dynptrs and implement malloc dynptrs Joanne Koong
2022-05-12 0:05 ` Daniel Borkmann
2022-05-12 20:03 ` Joanne Koong
2022-05-13 13:12 ` Daniel Borkmann
2022-05-13 16:39 ` Alexei Starovoitov
2022-05-13 19:28 ` Daniel Borkmann
2022-05-13 21:04 ` Andrii Nakryiko
2022-05-13 22:16 ` Alexei Starovoitov
2022-05-16 20:29 ` Joanne Koong
2022-05-16 20:52 ` Joanne Koong
2022-05-13 20:59 ` Andrii Nakryiko
2022-05-13 21:36 ` David Vernet
2022-05-09 22:42 ` [PATCH bpf-next v4 3/6] bpf: Dynptr support for ring buffers Joanne Koong
2022-05-13 21:02 ` Andrii Nakryiko
2022-05-16 16:09 ` David Vernet
2022-05-09 22:42 ` [PATCH bpf-next v4 4/6] bpf: Add bpf_dynptr_read and bpf_dynptr_write Joanne Koong
2022-05-13 21:06 ` Andrii Nakryiko
2022-05-16 16:56 ` David Vernet [this message]
2022-05-16 17:23 ` Joanne Koong
2022-05-09 22:42 ` [PATCH bpf-next v4 5/6] bpf: Add dynptr data slices Joanne Koong
2022-05-13 21:11 ` Andrii Nakryiko
2022-05-13 21:37 ` Alexei Starovoitov
2022-05-16 17:13 ` Joanne Koong
2022-05-09 22:42 ` [PATCH bpf-next v4 6/6] bpf: Dynptr tests Joanne Koong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220516165627.4a2kdpgzmln5ejew@dev0025.ash9.facebook.com \
--to=void@manifault.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=joannelkoong@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox