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 15/25] bpf: Teach verifier about non-size constant arguments
Date: Wed, 9 Nov 2022 21:59:48 +0530 [thread overview]
Message-ID: <20221109162948.wrv44sqmnu3sl5on@apollo> (raw)
In-Reply-To: <CAEf4BzaJbT0pN-tDXAgD67q3JyhjmRmyRRKYsiyjk6musyGdSQ@mail.gmail.com>
On Wed, Nov 09, 2022 at 05:35:26AM IST, Andrii Nakryiko wrote:
> On Mon, Nov 7, 2022 at 3:10 PM Kumar Kartikeya Dwivedi <memxor@gmail.com> wrote:
> >
> > Currently, the verifier has support for various arguments that either
> > describe the size of the memory being passed in to a helper, or describe
> > the size of the memory being returned. When a constant is passed in like
> > this, it is assumed for the purposes of precision tracking that if the
> > value in the already explored safe state is within the value in current
> > state, it would fine to prune the search.
> >
> > While this holds well for size arguments, arguments where each value may
> > denote a distinct meaning and needs to be verified separately needs more
> > work. Search can only be pruned if both are equivalent values. In all
> > other cases, it would be incorrect to treat those two precise registers
> > as equivalent if the new value satisfies the old one (i.e. old <= cur).
> >
> > Hence, make the register precision marker tri-state. There are now three
> > values that reg->precise takes: NOT_PRECISE, PRECISE, EXACT.
> >
> > Both PRECISE and EXACT are 'true' values. EXACT affects how regsafe
> > decides whether both registers are equivalent for the purposes of
> > verifier state equivalence. When it sees that old state register has
> > reg->precise == EXACT, unless both are equivalent, it will return false.
> > Otherwise, for PRECISE case it falls back to the default check that is
> > present now (i.e. thinking that we're talking about sizes).
> >
> > This is required as a future patch introduces a BPF memory allocator
> > interface, where we take the program BTF's type ID as an argument. Each
> > distinct type ID may result in the returned pointer obtaining a
> > different size, hence precision tracking is needed, and pruning cannot
> > just happen when the old value is within the current value. It must only
> > happen when the type ID is equal. The type ID will always correspond to
> > prog->aux->btf hence actual type match is not required.
> >
> > Finally, change mark_chain_precision precision argument to EXACT for
> > kfuncs constant non-size scalar arguments (tagged with __k suffix).
> >
> > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> > ---
>
> I think this needs a bit more thinking, tbh. First, with my recent
> changes we don't even set precision marks in current state, everything
> stays imprecise. And then under CAP_BPF we also aggressively reset
> precision. This might work for EXACT, but needs careful consideration.
>
I'm sorry, I didn't have the time to look at the series, but I spent the whole
day going over it today, and it makes a lot of sense to me. I think I also
misunderstood some things and going through it brought some clarity.
I think resetting precision is fine here too. As you've stated in that series,
the verifier while simulating execution in current state already checks
everything.
> But, taking a step back. I'm trying to understand why this whole EXACT
> mode is necessary. SCALAR has min/max values which regsafe() does
> check. So for those special ___k arguments, if we correctly set
> min/max values to be *exactly* the btf_id passed in, why would
> regsafe()'s logic not work?
>
Yes, when you have tnum_is_const var_off, regsafe will return false (when
reg->precise is true). So EXACT is unnecessary in that case.
I think you're probably right. The range_within will fail for k1 != k2,
but I was more concerned for cases where it's not a constant made a concrete
value later.
rX = ...; [X1, Y1];
if (cond) // unknown
rX = ...; [X2, Y2];
p:
...
p is a pruning point, so states will be compared there. I spent a fair amount of
time today trying to break this in different ways but failed so far. Also,
thinking about if it still lies within that range, things should still be ok
since it's in the same admissible set of values for the scalar that was later
refined and used as a constant for bpf_obj_new. So it's probably unncessary to
make things more pessimistic. The verifier will ensure the current value is
always a subset of the old value.
I guess I'll hold on for this patch and work towards getting the rest in first
(since Alexei mentioned others are waiting on this), and circle back to this if
I am able to construct a real test case that breaks. bpf_obj_new is already
behind CAP_BPF.
next prev parent reply other threads:[~2022-11-09 16:29 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
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 [this message]
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=20221109162948.wrv44sqmnu3sl5on@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