From: Yonghong Song <yhs@meta.com>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>, Yonghong Song <yhs@fb.com>
Cc: bpf@vger.kernel.org, Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
kernel-team@fb.com, Martin KaFai Lau <martin.lau@kernel.org>
Subject: Re: [PATCH bpf-next 5/7] bpf: Mark potential spilled loop index variable as precise
Date: Thu, 6 Apr 2023 09:55:37 -0700 [thread overview]
Message-ID: <4cd6c1b2-5e6a-1655-ab3d-1eda84aa4cbb@meta.com> (raw)
In-Reply-To: <CAEf4BzbhsWVK45OXBSY4tz9v-z-8j7ndMT=3BK4aDvza8FVnkA@mail.gmail.com>
On 4/4/23 3:09 PM, Andrii Nakryiko wrote:
> On Wed, Mar 29, 2023 at 10:56 PM Yonghong Song <yhs@fb.com> wrote:
>>
>> For a loop, if loop index variable is spilled and between loop
>> iterations, the only reg/spill state difference is spilled loop
>> index variable, then verifier may assume an infinite loop which
>> cause verification failure. In such cases, we should mark
>> spilled loop index variable as precise to differentiate states
>> between loop iterations.
>>
>> Since verifier is not able to accurately identify loop index
>> variable, add a heuristic such that if both old reg state and
>> new reg state are consts, mark old reg state as precise which
>> will trigger constant value comparison later.
>>
>> Signed-off-by: Yonghong Song <yhs@fb.com>
>> ---
>> kernel/bpf/verifier.c | 20 ++++++++++++++++++--
>> 1 file changed, 18 insertions(+), 2 deletions(-)
>>
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index d070943a8ba1..d1aa2c7ae7c0 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -14850,6 +14850,23 @@ static bool stacksafe(struct bpf_verifier_env *env, struct bpf_func_state *old,
>> /* Both old and cur are having same slot_type */
>> switch (old->stack[spi].slot_type[BPF_REG_SIZE - 1]) {
>> case STACK_SPILL:
>> + /* sometime loop index variable is spilled and the spill
>> + * is not marked as precise. If only state difference
>> + * between two iterations are spilled loop index, the
>> + * "infinite loop detected at insn" error will be hit.
>> + * Mark spilled constant as precise so it went through value
>> + * comparison.
>> + */
>> + old_reg = &old->stack[spi].spilled_ptr;
>> + cur_reg = &cur->stack[spi].spilled_ptr;
>> + if (!old_reg->precise) {
>> + if (old_reg->type == SCALAR_VALUE &&
>> + cur_reg->type == SCALAR_VALUE &&
>> + tnum_is_const(old_reg->var_off) &&
>> + tnum_is_const(cur_reg->var_off))
>> + old_reg->precise = true;
>> + }
>> +
>
> I'm very worried about heuristics like this. Thinking in abstract, if
> scalar's value is important for some loop invariant and would
> guarantee some jump to be always taken or not taken, then jump
> instruction prediction logic should mark register (and then by
> precision backtrack stack slot) as precise. But if precise values
> don't guarantee only one branch being taken, then marking the slot as
> precise makes no sense.
>
> Let's be very diligent with changes like this. I think your other
> patches should help already with marking necessary slots as precise,
> can you double check that this issue still happens. And if yes, let's
> address them as a separate feature. The rest of verifier logic changes
> in this patch set look good to me and make total sense.
Yes, this is a heuristic so it will mark precise for non-induction
variables as well. Let me do a little more study on this. Just posted v2
without this patch and its corresponding tests.
>
>
>> /* when explored and current stack slot are both storing
>> * spilled registers, check that stored pointers types
>> * are the same as well.
>> @@ -14860,8 +14877,7 @@ static bool stacksafe(struct bpf_verifier_env *env, struct bpf_func_state *old,
>> * such verifier states are not equivalent.
>> * return false to continue verification of this path
>> */
>> - if (!regsafe(env, &old->stack[spi].spilled_ptr,
>> - &cur->stack[spi].spilled_ptr, idmap))
>> + if (!regsafe(env, old_reg, cur_reg, idmap))
>> return false;
>> break;
>> case STACK_DYNPTR:
>> --
>> 2.34.1
>>
next prev parent reply other threads:[~2023-04-06 16:56 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-30 5:56 [PATCH bpf-next 0/7] bpf: Improve verifier for cond_op and spilled loop index variables Yonghong Song
2023-03-30 5:56 ` [PATCH bpf-next 1/7] bpf: Improve verifier JEQ/JNE insn branch taken checking Yonghong Song
2023-03-30 21:14 ` Dave Marchevsky
2023-03-31 6:40 ` Yonghong Song
2023-03-30 5:56 ` [PATCH bpf-next 2/7] selftests/bpf: Add tests for non-constant cond_op NE/EQ bound deduction Yonghong Song
2023-03-30 5:56 ` [PATCH bpf-next 3/7] bpf: Improve handling of pattern '<const> <cond_op> <non_const>' in verifier Yonghong Song
2023-03-30 22:54 ` Dave Marchevsky
2023-03-31 15:26 ` Yonghong Song
2023-04-04 22:04 ` Andrii Nakryiko
2023-04-06 16:51 ` Yonghong Song
2023-03-30 5:56 ` [PATCH bpf-next 4/7] selftests/bpf: Add verifier tests for code pattern '<const> <cond_op> <non_const>' Yonghong Song
2023-03-30 5:56 ` [PATCH bpf-next 5/7] bpf: Mark potential spilled loop index variable as precise Yonghong Song
2023-03-31 21:54 ` Eduard Zingerman
2023-03-31 23:39 ` Yonghong Song
2023-04-03 1:48 ` Alexei Starovoitov
2023-04-03 4:04 ` Yonghong Song
2023-04-04 22:09 ` Andrii Nakryiko
2023-04-06 16:55 ` Yonghong Song [this message]
2023-03-30 5:56 ` [PATCH bpf-next 6/7] selftests/bpf: Remove previous workaround for test verif_scale_loop6 Yonghong Song
2023-03-30 5:56 ` [PATCH bpf-next 7/7] selftests/bpf: Add a new test based on loop6.c Yonghong Song
2023-04-03 1:39 ` Alexei Starovoitov
2023-04-03 3:59 ` Yonghong Song
2023-04-04 21:46 ` [PATCH bpf-next 0/7] bpf: Improve verifier for cond_op and spilled loop index variables Andrii Nakryiko
2023-04-06 16:49 ` Yonghong Song
2023-04-06 18:38 ` Andrii Nakryiko
2023-04-06 19:54 ` Alexei Starovoitov
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=4cd6c1b2-5e6a-1655-ab3d-1eda84aa4cbb@meta.com \
--to=yhs@meta.com \
--cc=andrii.nakryiko@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=kernel-team@fb.com \
--cc=martin.lau@kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox