Re: [PATCH bpf-next v3 5/6] bpf: Add dynptr data slices

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Apr 28, 2022 at 2:12 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>
> ---
>  include/linux/bpf.h            |  4 +++
>  include/uapi/linux/bpf.h       | 12 +++++++
>  kernel/bpf/helpers.c           | 28 +++++++++++++++
>  kernel/bpf/verifier.c          | 64 ++++++++++++++++++++++++++++++----
>  tools/include/uapi/linux/bpf.h | 12 +++++++
>  5 files changed, 114 insertions(+), 6 deletions(-)
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index b276dbf942dd..4d2de868bdbc 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -397,6 +397,9 @@ enum bpf_type_flag {
>         /* DYNPTR points to a ringbuf record. */
>         DYNPTR_TYPE_RINGBUF     = BIT(9 + BPF_BASE_TYPE_BITS),
>
> +       /* MEM is memory owned by a dynptr */
> +       MEM_DYNPTR              = BIT(10 + BPF_BASE_TYPE_BITS),

do we need this yet another bit? It seems like it only matters for
verifier log dynptr_ output? Can we just reuse MEM_ALLOC? Or there is
some ringbuf-specific logic that we'll interfere with? If feels a bit
unnecessary, let's think if we can avoid adding bits just for this.

> +
>         __BPF_TYPE_LAST_FLAG    = DYNPTR_TYPE_RINGBUF,
>  };
>

[...]

> +               if (is_dynptr_ref_function(func_id)) {
> +                       int i;
> +
> +                       /* Find the id of the dynptr we're acquiring a reference to */
> +                       for (i = 0; i < MAX_BPF_FUNC_REG_ARGS; i++) {
> +                               if (arg_type_is_dynptr(fn->arg_type[i])) {
> +                                       id = stack_slot_get_id(env, &regs[BPF_REG_1 + i]);

let's make sure that we have only one such argument?

> +                                       break;
> +                               }
> +                       }
> +                       if (unlikely(i == MAX_BPF_FUNC_REG_ARGS)) {

please don't use unlikely(), especially for non-performance critical code path

> +                               verbose(env, "verifier internal error: no dynptr args to a dynptr ref function");
> +                               return -EFAULT;
> +                       }
> +               } else {
> +                       id = acquire_reference_state(env, insn_idx);
> +                       if (id < 0)
> +                               return id;
> +               }

[...]



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux