BPF List
 help / color / mirror / Atom feed
From: Eduard Zingerman <eddyz87@gmail.com>
To: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com>,
	Alexei Starovoitov <alexei.starovoitov@gmail.com>,
	Andrew Werner <awerner32@gmail.com>, bpf <bpf@vger.kernel.org>,
	Andrei Matei <andreimatei1@gmail.com>,
	Tamir Duberstein <tamird@gmail.com>,
	Joanne Koong <joannelkoong@gmail.com>,
	 kernel-team@dataexmachina.dev, Song Liu <song@kernel.org>
Subject: Re: [BUG] verifier escape with iteration helpers (bpf_loop, ...)
Date: Mon, 18 Sep 2023 16:06:14 +0300	[thread overview]
Message-ID: <a2995c1d7c01794ca9b652cdea7917cac5d98a16.camel@gmail.com> (raw)
In-Reply-To: <CAP01T76duVGmnb+LQjhdKneVYs1q=ehU4yzTLmgZdG0r2ErOYQ@mail.gmail.com>

On Mon, 2023-09-18 at 00:09 +0200, Kumar Kartikeya Dwivedi wrote:
[...]
> 
> I was planning to get to this eventually, but it's great if you are
> looking to do it.
> 
> > After some analysis I decided to go with Alexei's suggestion and
> > implement something similar to iterators for selected set of helper
> > functions that accept "looping" callbacks, such as:
> > - bpf_loop
> > - bpf_for_each_map_elem
> > - bpf_user_ringbuf_drain
> > - bpf_timer_set_callback (?)
> > 
> 
> The last one won't require this, I think. The callback only runs once,
> and asynchronously.
> Others you are missing are bpf_find_vma and the bpf_rbtree_add kfunc.
> While the latter is not an interator, it can invoke the same callback
> an unknown number of times.

Noted, thank you.

> The other major thing that needs to be checked is cases where callback
> will be executed zero times. There is some discussion on this in [0],
> where this bug was reported originally. Basically, we need to explore
> a path where the callback execution does not happen and ensure the
> program is still safe.
> 
> [0]: https://lore.kernel.org/bpf/CAP01T74cOJzo3xQcW6weURH+mYRQ7kAWMqQOgtd_ymSbhrOoMQ@mail.gmail.com
> 
> You could also consider taking the selftests from this link, some of
> them allow completely breaking safety properties of the verifier.

Thank you, I missed this thread.

[...]
> > I have a patch (at the end of this email) that correctly recognizes
> > the bpf_loop example in this thread as unsafe. However this patch has
> > a few deficiencies:
> > 
> > - verif_scale_strobemeta_bpf_loop selftest is not passing, because
> >   read_map_var function invoked from the callback continuously
> >   increments 'payload' pointer used in subsequent iterations.
> > 
> >   In order to handle such code I need to add an upper bound tracking
> >   for iteration depth (when such bound could be deduced).
> > 
> 
> Yes, either the loop converges before the upper limit is hit, or we
> keep unrolling it until we exhaust the deduced loop count passed to
> the bpf_loop helper. But we will need to mark the loop count argument
> register as precise when we make use of its value in such a case.

Yes, marking counter as precise makes sense but I think it would
happen automatically. My current plan is to mark index register as
bounded and use depth tracking only internally to decide whether to
schedule another "active" iteration state. If that would not be
sufficient, I will try assigning specific values for loop counter
(hesitate to do it to avoid conflict with convergence detection).

[...]
> > - the callback as bellow currently causes state explosion:
> > 
> >   static int precise1_callback(__u32 idx, struct precise1_ctx *ctx)
> >   {
> >       if (idx == 0)
> >           ctx->a = 1;
> >       if (idx == 1 && ctx->a == 1)
> >           ctx->b = 1;
> >       return 0;
> >   }
> > 
> >   I'm not sure yet what to do about this, there are several possibilities:
> >   - tweak the order in which states are visited (need to think about it);
> >   - check states in bpf_verifier_env::head (not explored yet) for
> >     equivalence and avoid enqueuing duplicate states.
> > 
> > 
> > I'll proceed addressing the issues above on Monday.
> > 
> 
> I think there is a class of programs that are nevertheless going to be
> broken now, as bpf_loop and others basically permitted incorrect code
> to pass through. And the iteration until we arrive at a fixpoint won't
> be able to cover all classes of loop bodies, so I think we will need
> to make a tradeoff in terms of expressibility vs verifier complexity.
> In general, cases like this with branches/conditional exit from the
> loop body which do not converge will lead to state explosion anyway.

This might be the case, however I found that specific issue with
"precise1_callback" could be resolved by using mark_force_checkpoint()
to mark iteration back-edges (same way it is done for regular iterators).
So maybe impact won't be that bad.

Thanks,
Eduard

  reply	other threads:[~2023-09-18 16:15 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-07 14:04 [BUG] verifier escape with iteration helpers (bpf_loop, ...) Andrew Werner
2023-07-07 16:44 ` Alexei Starovoitov
2023-07-07 18:08   ` Andrii Nakryiko
2023-07-07 18:21     ` Andrew Werner
2023-09-17 21:37     ` Eduard Zingerman
2023-09-17 22:09       ` Kumar Kartikeya Dwivedi
2023-09-18 13:06         ` Eduard Zingerman [this message]
2023-09-19 16:28           ` Eduard Zingerman
2023-09-19 23:02             ` Andrii Nakryiko
2023-09-20  0:19               ` Eduard Zingerman
2023-09-20 16:20                 ` Eduard Zingerman
2023-09-20 16:57                   ` Andrii Nakryiko
2023-09-21  9:14                 ` Alexei Starovoitov
2023-09-21 11:03                   ` Eduard Zingerman
2023-09-21 12:56                     ` Alexei Starovoitov
2023-09-21 16:23                       ` Eduard Zingerman
2023-09-21 16:35                         ` Andrii Nakryiko
2023-09-21 18:16                           ` Eduard Zingerman
2023-09-22  1:01                             ` Eduard Zingerman
2023-09-22  2:48                               ` Andrii Nakryiko
2023-09-22 18:36                                 ` Eduard Zingerman
2023-09-22 20:52                                   ` Andrii Nakryiko
2023-09-25  1:01                                     ` Eduard Zingerman
2023-09-26  0:33                                       ` Andrii Nakryiko
2023-09-26 15:55                                         ` Eduard Zingerman
2023-09-26 16:25                                           ` Andrii Nakryiko
2023-09-28  1:09                                             ` Eduard Zingerman
2023-09-28 18:30                                               ` Andrii Nakryiko
2023-10-02  3:26                                                 ` Eduard Zingerman
2023-09-30  0:41                                               ` Alexei Starovoitov
2023-10-02  1:40                                                 ` Eduard Zingerman
2023-10-02 16:29                                                   ` Alexei Starovoitov
2023-10-02 17:18                                                     ` Eduard Zingerman
2023-10-03  0:05                                                       ` Alexei Starovoitov
2023-10-03  2:00                                                         ` Alexei Starovoitov
2023-10-03 15:33                                                         ` Eduard Zingerman
2023-10-03 16:07                                                           ` Alexei Starovoitov
2023-10-03 18:50                                                           ` Alexei Starovoitov
2023-10-03 21:52                                                             ` Eduard Zingerman
2023-10-03 22:03                                                               ` Eduard Zingerman
2023-10-03 23:08                                                               ` Alexei Starovoitov
2023-10-03 23:14                                                                 ` Eduard Zingerman
2023-10-04  0:22                                                                   ` Andrii Nakryiko
2023-10-04  1:05                                                                 ` Eduard Zingerman
2023-10-04  2:57                                                                   ` Alexei Starovoitov
2023-10-04  5:50                                                                     ` Alexei Starovoitov
2023-10-04  9:49                                                                       ` Eduard Zingerman
2023-10-04 11:52                                                                     ` Eduard Zingerman
2023-09-19 23:14       ` Andrii Nakryiko
2023-09-20  0:06         ` Eduard Zingerman
2023-09-20 16:37           ` Andrii Nakryiko
2023-09-20 17:13             ` Eduard Zingerman

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=a2995c1d7c01794ca9b652cdea7917cac5d98a16.camel@gmail.com \
    --to=eddyz87@gmail.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=andreimatei1@gmail.com \
    --cc=andrii.nakryiko@gmail.com \
    --cc=awerner32@gmail.com \
    --cc=bpf@vger.kernel.org \
    --cc=joannelkoong@gmail.com \
    --cc=kernel-team@dataexmachina.dev \
    --cc=memxor@gmail.com \
    --cc=song@kernel.org \
    --cc=tamird@gmail.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