All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: bpf <bpf@vger.kernel.org>,
	"Network Development" <netdev@vger.kernel.org>,
	netfilter-devel <netfilter-devel@vger.kernel.org>,
	"Alexei Starovoitov" <ast@kernel.org>,
	"Daniel Borkmann" <daniel@iogearbox.net>,
	"Andrii Nakryiko" <andrii@kernel.org>,
	"Martin KaFai Lau" <kafai@fb.com>,
	"Song Liu" <songliubraving@fb.com>, "Yonghong Song" <yhs@fb.com>,
	"John Fastabend" <john.fastabend@gmail.com>,
	"Maxim Mikityanskiy" <maximmi@nvidia.com>,
	"Pablo Neira Ayuso" <pablo@netfilter.org>,
	"Florian Westphal" <fw@strlen.de>,
	"Jesper Dangaard Brouer" <brouer@redhat.com>,
	"Toke Høiland-Jørgensen" <toke@redhat.com>
Subject: Re: [PATCH bpf-next v4 06/10] bpf: Track provenance for pointers formed from referenced PTR_TO_BTF_ID
Date: Sun, 19 Dec 2021 10:03:49 +0530	[thread overview]
Message-ID: <20211219043349.mmycwjnxcqc7lc2c@apollo.legion> (raw)
In-Reply-To: <CAADnVQJ43O-eavsMuqW0kCiBZMf4PFHbFhSPa7vRWY1cjwqFAg@mail.gmail.com>

On Sun, Dec 19, 2021 at 09:30:32AM IST, Alexei Starovoitov wrote:
> On Sat, Dec 18, 2021 at 7:18 PM Kumar Kartikeya Dwivedi
> <memxor@gmail.com> wrote:
> >
> > On Sun, Dec 19, 2021 at 07:58:39AM IST, Alexei Starovoitov wrote:
> > > On Fri, Dec 17, 2021 at 07:20:27AM +0530, Kumar Kartikeya Dwivedi wrote:
> > > > diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
> > > > index b80fe5bf2a02..a6ef11db6823 100644
> > > > --- a/include/linux/bpf_verifier.h
> > > > +++ b/include/linux/bpf_verifier.h
> > > > @@ -128,6 +128,16 @@ struct bpf_reg_state {
> > > >      * allowed and has the same effect as bpf_sk_release(sk).
> > > >      */
> > > >     u32 ref_obj_id;
> > > > +   /* This is set for pointers which are derived from referenced
> > > > +    * pointer (e.g. PTR_TO_BTF_ID pointer walking), so that the
> > > > +    * pointers obtained by walking referenced PTR_TO_BTF_ID
> > > > +    * are appropriately invalidated when the lifetime of their
> > > > +    * parent object ends.
> > > > +    *
> > > > +    * Only one of ref_obj_id and parent_ref_obj_id can be set,
> > > > +    * never both at once.
> > > > +    */
> > > > +   u32 parent_ref_obj_id;
> > >
> > > How would it handle parent of parent?
> >
> > When you do:
> >
> > r1 = acquire();
> >
> > it gets ref_obj_id as N, then when you load r1->next, it does mark_btf_ld_reg
> > with reg->ref_obj_id ?: reg->parent_ref_obj_id, the latter is zero so it copies
> > ref, but into parent_ref_obj_id.
> >
> > r2 = r1->next;
> >
> > From here on, parent_ref_obj_id is propagated into all further mark_btf_ld_reg,
> > so if we do since ref_obj_id will be zero from previous mark_btf_ld_reg:
> >
> > r3 = r2->next; // it will copy parent_ref_obj_id
> >
> > I think it even works fine when you reach it indirectly, like foo->bar->foo,
> > if first foo is referenced.
> >
> > ... but maybe I missed some detail, do you see a problem in this approach?
> >
> > > Did you consider map_uid approach ?
> > > Similar uid can be added for PTR_TO_BTF_ID.
> > > Then every such pointer will be unique. Each deref will get its own uid.
> >
> > I'll look into it, I didn't consider it before. My idea was to invalidate
> > pointers obtained from a referenced ptr_to_btf_id so I copied the same
> > ref_obj_id into parent_ref_obj_id, so that it can be matched during release. How
> > would that work in the btf_uid approach if they are unique? Do we copy the same
> > ref_obj_id into btf_uid? Then it's not very different except being btf_id ptr
> > specific state, right?
> >
> > Or we can copy ref_obj_id and also set uid to disallow it from being released,
> > but still allow invalidation.
>
> The goal is to disallow:
> struct foo { struct foo *next; };
>
> r1 = acquire(...); // BTF ID of struct foo
> if (r1) {
>         r2 = r1->next;
>         release(r2);
> }
>
> right?

Yes, but not just that, we also want to prevent use of r2 after release(r1).
Then snippet above is problematic if we get same BTF ID ptr in r2 and try to
solve that in the naive way (just copy ref_obj_id in dst_reg), because
verifier will not be able to distinguish between r1 and r2 for purposes of
release kfunc call.

> With btf_uid approach each deref gets its own uid.
> r2 = r1->next
> and
> r3 = r1->next
> will get different uids.
> When type == PTR_TO_BTF_ID its reg->ref_obj_id will be considered
> together with btf_uid.
> Both ref_obj_id and btf_uid need to be the same.
>

That will indeed work, I can rework it this way. After acquire_reference_state
we can set btf_uid = ref_obj_id, then simply assign fresh btf_uid on
mark_btf_ld_reg.

Not pushing back, but I am trying to understand why you think this is better
than simply doing it the way in this patch? What additional cases is btf_uid
approach considering that I am missing? I don't understand what we get if each
deref gets its own unique btf_uid.

There are only two objectives: prevent use of r2 after r1 is gone, and prevent
r2 being passed into release kfunc (discovered when I simply copied ref_obj_id).

> But let's go back a bit.
> Why ref_obj_id is copied on deref?

It is, but into parent_ref_obj_id, to match during release_reference.

> Shouldn't r2 get a different ref_obj_id after r2 = r1->next ?

It's ref_obj_id is still 0.

Thinking about this more, we actually only need 1 extra bit of information in
reg_state, not even a new member. We can simply copy ref_obj_id and set this
bit, then we can reject this register during release but consider it during
release_reference.

--
Kartikeya

  reply	other threads:[~2021-12-19  4:33 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-17  1:50 [PATCH bpf-next v4 00/10] Introduce unstable CT lookup helpers Kumar Kartikeya Dwivedi
2021-12-17  1:50 ` [PATCH bpf-next v4 01/10] bpf: Refactor bpf_check_mod_kfunc_call Kumar Kartikeya Dwivedi
2021-12-17  1:50 ` [PATCH bpf-next v4 02/10] bpf: Remove DEFINE_KFUNC_BTF_ID_SET Kumar Kartikeya Dwivedi
2021-12-17  1:50 ` [PATCH bpf-next v4 03/10] bpf: Extend kfunc with PTR_TO_CTX, PTR_TO_MEM argument support Kumar Kartikeya Dwivedi
2021-12-19  2:17   ` Alexei Starovoitov
2021-12-19  3:21     ` Kumar Kartikeya Dwivedi
2021-12-17  1:50 ` [PATCH bpf-next v4 04/10] bpf: Introduce mem, size argument pair support for kfunc Kumar Kartikeya Dwivedi
2021-12-19  2:19   ` Alexei Starovoitov
2021-12-19  2:53     ` Kumar Kartikeya Dwivedi
2021-12-17  1:50 ` [PATCH bpf-next v4 05/10] bpf: Add reference tracking support to kfunc Kumar Kartikeya Dwivedi
2021-12-19  2:22   ` Alexei Starovoitov
2021-12-19  3:01     ` Kumar Kartikeya Dwivedi
2021-12-19  3:54       ` Alexei Starovoitov
2021-12-19  4:38         ` Kumar Kartikeya Dwivedi
2021-12-19  4:50           ` Alexei Starovoitov
2021-12-17  1:50 ` [PATCH bpf-next v4 06/10] bpf: Track provenance for pointers formed from referenced PTR_TO_BTF_ID Kumar Kartikeya Dwivedi
2021-12-19  2:28   ` Alexei Starovoitov
2021-12-19  3:18     ` Kumar Kartikeya Dwivedi
2021-12-19  4:00       ` Alexei Starovoitov
2021-12-19  4:33         ` Kumar Kartikeya Dwivedi [this message]
2021-12-19  5:05           ` Alexei Starovoitov
2021-12-19  5:25             ` Kumar Kartikeya Dwivedi
2021-12-19 17:43               ` Alexei Starovoitov
2021-12-19 18:10                 ` Kumar Kartikeya Dwivedi
2021-12-19 19:08                   ` Alexei Starovoitov
2021-12-19 19:56                     ` Kumar Kartikeya Dwivedi
2021-12-19 21:26                       ` Alexei Starovoitov
2021-12-19 21:54                         ` Kumar Kartikeya Dwivedi
2021-12-17  1:50 ` [PATCH bpf-next v4 07/10] net/netfilter: Add unstable CT lookup helpers for XDP and TC-BPF Kumar Kartikeya Dwivedi
2021-12-17  8:18   ` Pablo Neira Ayuso
2021-12-17  8:40     ` Kumar Kartikeya Dwivedi
2021-12-17  1:50 ` [PATCH bpf-next v4 08/10] selftests/bpf: Add test for unstable CT lookup API Kumar Kartikeya Dwivedi
2021-12-17  1:50 ` [PATCH bpf-next v4 09/10] selftests/bpf: Add test_verifier support to fixup kfunc call insns Kumar Kartikeya Dwivedi
2021-12-17  1:50 ` [PATCH bpf-next v4 10/10] selftests/bpf: Extend kfunc selftests Kumar Kartikeya Dwivedi
2021-12-17  9:36 ` [PATCH bpf-next v4 00/10] Introduce unstable CT lookup helpers Kumar Kartikeya Dwivedi
2021-12-17 16:40   ` Andrii Nakryiko

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=20211219043349.mmycwjnxcqc7lc2c@apollo.legion \
    --to=memxor@gmail.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=brouer@redhat.com \
    --cc=daniel@iogearbox.net \
    --cc=fw@strlen.de \
    --cc=john.fastabend@gmail.com \
    --cc=kafai@fb.com \
    --cc=maximmi@nvidia.com \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    --cc=songliubraving@fb.com \
    --cc=toke@redhat.com \
    --cc=yhs@fb.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.