public inbox for bpf@vger.kernel.org
 help / color / mirror / Atom feed
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
>>

  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