BPF List
 help / color / mirror / Atom feed
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: bpf@vger.kernel.org, Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Martin KaFai Lau <martin.lau@kernel.org>,
	Dave Marchevsky <davemarchevsky@meta.com>,
	Delyan Kratunov <delyank@meta.com>
Subject: Re: [PATCH bpf-next v5 06/25] bpf: Introduce local kptrs
Date: Wed, 9 Nov 2022 05:30:16 +0530	[thread overview]
Message-ID: <20221109000016.np325iqjjegvdose@apollo> (raw)
In-Reply-To: <CAEf4BzZRaN_zd07jvtom6QJEEDGmFQTLJy4BM1bKi1MH5+n5QA@mail.gmail.com>

On Wed, Nov 09, 2022 at 04:59:41AM IST, Andrii Nakryiko wrote:
> On Mon, Nov 7, 2022 at 3:10 PM Kumar Kartikeya Dwivedi <memxor@gmail.com> wrote:
> >
> > Introduce local kptrs, i.e. PTR_TO_BTF_ID that point to a type in
> > program BTF. This is indicated by the presence of MEM_ALLOC type flag in
> > reg->type to avoid having to check btf_is_kernel when trying to match
> > argument types in helpers.
> >
> > Refactor btf_struct_access callback to just take bpf_reg_state instead
> > of btf and btf_type paramters. Note that the call site in
> > check_map_access now simulates access to a PTR_TO_BTF_ID by creating a
> > dummy reg on stack. Since only the type, btf, and btf_id of the register
> > matter for the checks, it can be done so without complicating the usual
> > cases elsewhere in the verifier where reg->btf and reg->btf_id is used
> > verbatim.
> >
> > Whenever walking such types, any pointers being walked will always yield
> > a SCALAR instead of pointer. In the future we might permit kptr inside
> > local kptr (either kernel or local), and it would be permitted only in
> > that case.
> >
> > For now, these local kptrs will always be referenced in verifier
> > context, hence ref_obj_id == 0 for them is a bug. It is allowed to write
> > to such objects, as long fields that are special are not touched
> > (support for which will be added in subsequent patches). Note that once
> > such a local kptr is marked PTR_UNTRUSTED, it is no longer allowed to
> > write to it.
> >
> > No PROBE_MEM handling is therefore done for loads into this type unless
> > PTR_UNTRUSTED is part of the register type, since they can never be in
> > an undefined state, and their lifetime will always be valid.
> >
> > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> > ---
> >  include/linux/bpf.h              | 28 ++++++++++++++++--------
> >  include/linux/filter.h           |  8 +++----
> >  kernel/bpf/btf.c                 | 16 ++++++++++----
> >  kernel/bpf/verifier.c            | 37 ++++++++++++++++++++++++++------
> >  net/bpf/bpf_dummy_struct_ops.c   | 14 ++++++------
> >  net/core/filter.c                | 34 ++++++++++++-----------------
> >  net/ipv4/bpf_tcp_ca.c            | 13 ++++++-----
> >  net/netfilter/nf_conntrack_bpf.c | 17 ++++++---------
> >  8 files changed, 99 insertions(+), 68 deletions(-)
> >
> > diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> > index afc1c51b59ff..75dbd2ecf80a 100644
> > --- a/include/linux/bpf.h
> > +++ b/include/linux/bpf.h
> > @@ -524,6 +524,11 @@ enum bpf_type_flag {
> >         /* Size is known at compile time. */
> >         MEM_FIXED_SIZE          = BIT(10 + BPF_BASE_TYPE_BITS),
> >
> > +       /* MEM is of a type from program BTF, not kernel BTF. This is used to
> > +        * tag PTR_TO_BTF_ID allocated using bpf_obj_new.
> > +        */
> > +       MEM_ALLOC               = BIT(11 + BPF_BASE_TYPE_BITS),
> > +
>
> you fixed one naming confusion with RINGBUF and basically are creating
> a new one, where "ALLOC" means "local kptr"... If we are stuck with
> "local kptr" (which I find very confusing as well, but that's beside
> the point), why not stick to the whole "local" terminology here?
> MEM_LOCAL?
>

See the discussion about this in v4:
https://lore.kernel.org/bpf/20221104075113.5ighwdvero4mugu7@apollo

It was MEM_TYPE_LOCAL before. Also, better naming suggestions are always
welcome, I asked the same in that message as well.

> >         __BPF_TYPE_FLAG_MAX,
> >         __BPF_TYPE_LAST_FLAG    = __BPF_TYPE_FLAG_MAX - 1,
> >  };
> > @@ -771,6 +776,7 @@ struct bpf_prog_ops {
> >                         union bpf_attr __user *uattr);
> >  };
> >
>
> [...]
>
> > -int btf_struct_access(struct bpf_verifier_log *log, const struct btf *btf,
> > -                     const struct btf_type *t, int off, int size,
> > -                     enum bpf_access_type atype __maybe_unused,
> > +int btf_struct_access(struct bpf_verifier_log *log,
> > +                     const struct bpf_reg_state *reg,
> > +                     int off, int size, enum bpf_access_type atype __maybe_unused,
> >                       u32 *next_btf_id, enum bpf_type_flag *flag)
> >  {
> > +       const struct btf *btf = reg->btf;
> >         enum bpf_type_flag tmp_flag = 0;
> > +       const struct btf_type *t;
> > +       u32 id = reg->btf_id;
> >         int err;
> > -       u32 id;
> >
> > +       t = btf_type_by_id(btf, id);
> >         do {
> >                 err = btf_struct_walk(log, btf, t, off, size, &id, &tmp_flag);
> >
> >                 switch (err) {
> >                 case WALK_PTR:
> > +                       /* For local types, the destination register cannot
> > +                        * become a pointer again.
> > +                        */
> > +                       if (type_is_local_kptr(reg->type))
> > +                               return SCALAR_VALUE;
>
> passing the entire bpf_reg_state just to differentiate between local
> vs kernel pointer seems like a huge overkill. bpf_reg_state is quite a
> complicated and extensive amount of state, and it seems cleaner to
> just pass it as a flag whether to allow pointer chasing or not. At
> least then we know we only care about that specific aspect, not about
> dozens of other possible fields of bpf_reg_state.
>

I agree that the separation is usually better, especially because this is also a
callback. I don't feel too strong about this though, we certainly do pass the
whole reg to functions which only work on a specific type of pointer. Though the
concern in this case is justified as it's not only an internal function but also
a callback.

It was just a bool in the RFC.
But in https://lore.kernel.org/bpf/20220907233023.x3uclwlnjuhftvtb@macbook-pro-4.dhcp.thefacebook.com
Alexei suggested passing reg instead.
From the link:
> imo it's cleaner to pass 'reg' instead of 'reg->btf',
> so we don't have to pass another boolean.
> And check type_is_local(reg) inside btf_struct_access().

  reply	other threads:[~2022-11-09  0:00 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-07 23:09 [PATCH bpf-next v5 00/25] Local kptrs, BPF linked lists Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 01/25] bpf: Remove BPF_MAP_OFF_ARR_MAX Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 02/25] bpf: Fix copy_map_value, zero_map_value Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 03/25] bpf: Support bpf_list_head in map values Kumar Kartikeya Dwivedi
2022-11-08 23:01   ` Andrii Nakryiko
2022-11-08 23:39     ` Kumar Kartikeya Dwivedi
2022-11-09  0:22       ` Andrii Nakryiko
2022-11-09  1:03         ` Alexei Starovoitov
2022-11-09 16:41           ` Kumar Kartikeya Dwivedi
2022-11-09 23:14             ` Andrii Nakryiko
2022-11-09 23:11           ` Andrii Nakryiko
2022-11-09 23:35             ` Alexei Starovoitov
2022-11-07 23:09 ` [PATCH bpf-next v5 04/25] bpf: Rename RET_PTR_TO_ALLOC_MEM Kumar Kartikeya Dwivedi
2022-11-08 23:08   ` Andrii Nakryiko
2022-11-07 23:09 ` [PATCH bpf-next v5 05/25] bpf: Rename MEM_ALLOC to MEM_RINGBUF Kumar Kartikeya Dwivedi
2022-11-08 23:14   ` Andrii Nakryiko
2022-11-08 23:49     ` Kumar Kartikeya Dwivedi
2022-11-09  0:26       ` Andrii Nakryiko
2022-11-09  1:05         ` Alexei Starovoitov
2022-11-09 22:58           ` Andrii Nakryiko
2022-11-07 23:09 ` [PATCH bpf-next v5 06/25] bpf: Introduce local kptrs Kumar Kartikeya Dwivedi
2022-11-08 23:29   ` Andrii Nakryiko
2022-11-09  0:00     ` Kumar Kartikeya Dwivedi [this message]
2022-11-09  0:36       ` Andrii Nakryiko
2022-11-09  1:32         ` Alexei Starovoitov
2022-11-09 17:00           ` Kumar Kartikeya Dwivedi
2022-11-09 23:23             ` Andrii Nakryiko
2022-11-09 23:21           ` Andrii Nakryiko
2022-11-07 23:09 ` [PATCH bpf-next v5 07/25] bpf: Recognize bpf_{spin_lock,list_head,list_node} in " Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 08/25] bpf: Verify ownership relationships for user BTF types Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 09/25] bpf: Allow locking bpf_spin_lock in local kptr Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 10/25] bpf: Allow locking bpf_spin_lock global variables Kumar Kartikeya Dwivedi
2022-11-08 23:37   ` Andrii Nakryiko
2022-11-09  0:03     ` Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 11/25] bpf: Allow locking bpf_spin_lock in inner map values Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 12/25] bpf: Rewrite kfunc argument handling Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 13/25] bpf: Drop kfunc bits from btf_check_func_arg_match Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 14/25] bpf: Support constant scalar arguments for kfuncs Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 15/25] bpf: Teach verifier about non-size constant arguments Kumar Kartikeya Dwivedi
2022-11-09  0:05   ` Andrii Nakryiko
2022-11-09 16:29     ` Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 16/25] bpf: Introduce bpf_obj_new Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 17/25] bpf: Introduce bpf_obj_drop Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 18/25] bpf: Permit NULL checking pointer with non-zero fixed offset Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 19/25] bpf: Introduce single ownership BPF linked list API Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 20/25] bpf: Add 'release on unlock' logic for bpf_list_push_{front,back} Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 21/25] selftests/bpf: Add __contains macro to bpf_experimental.h Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 22/25] selftests/bpf: Update spinlock selftest Kumar Kartikeya Dwivedi
2022-11-09  0:13   ` Andrii Nakryiko
2022-11-09 16:32     ` Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 23/25] selftests/bpf: Add failure test cases for spin lock pairing Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 24/25] selftests/bpf: Add BPF linked list API tests Kumar Kartikeya Dwivedi
2022-11-07 23:09 ` [PATCH bpf-next v5 25/25] selftests/bpf: Add BTF sanity tests Kumar Kartikeya Dwivedi
2022-11-09  0:18   ` Andrii Nakryiko
2022-11-09 16:33     ` Kumar Kartikeya Dwivedi

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=20221109000016.np325iqjjegvdose@apollo \
    --to=memxor@gmail.com \
    --cc=andrii.nakryiko@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davemarchevsky@meta.com \
    --cc=delyank@meta.com \
    --cc=martin.lau@kernel.org \
    /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