Re: [iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-07-14 Thread Y Song via iovisor-dev
I did an experiment with one of our internal bpf programs.
The program has 1563 insns.

Without Edward's patch:
processed 13634 insns, stack depth 160

With Edward's patch:
processed 15807 insns, stack depth 160

So the number of processed insns regressed by roughly 16%.
Did anybody do any similar experiments to quantify the patch's
impact in verification performance (e.g., in terms of processed insns)?

On Tue, Jun 27, 2017 at 5:53 AM, Edward Cree via iovisor-dev
 wrote:
> This series simplifies alignment tracking, generalises bounds tracking and
>  fixes some bounds-tracking bugs in the BPF verifier.  Pointer arithmetic on
>  packet pointers, stack pointers, map value pointers and context pointers has
>  been unified, and bounds on these pointers are only checked when the pointer
>  is dereferenced.
> Operations on pointers which destroy all relation to the original pointer
>  (such as multiplies and shifts) are disallowed if !env->allow_ptr_leaks,
>  otherwise they convert the pointer to an unknown scalar and feed it to the
>  normal scalar arithmetic handling.
> Pointer types have been unified with the corresponding adjusted-pointer types
>  where those existed (e.g. PTR_TO_MAP_VALUE[_ADJ] or FRAME_PTR vs
>  PTR_TO_STACK); similarly, CONST_IMM and UNKNOWN_VALUE have been unified into
>  SCALAR_VALUE.
> Pointer types (except CONST_PTR_TO_MAP, PTR_TO_MAP_VALUE_OR_NULL and
>  PTR_TO_PACKET_END, which do not allow arithmetic) have a 'fixed offset' and
>  a 'variable offset'; the former is used when e.g. adding an immediate or a
>  known-constant register, as long as it does not overflow.  Otherwise the
>  latter is used, and any operation creating a new variable offset creates a
>  new 'id' (and, for PTR_TO_PACKET, clears the 'range').
> SCALAR_VALUEs use the 'variable offset' fields to track the range of possible
>  values; the 'fixed offset' should never be set on a scalar.
>
> As of patch 12/12, all tests of tools/testing/selftests/bpf/test_verifier
>  and tools/testing/selftests/bpf/test_align pass.
>
> v3: added a few more tests; removed RFC tags.
>
> v2: fixed nfp build, made test_align pass again and extended it with a few
>  new tests (though still need to add more).
>
> Edward Cree (12):
>   selftests/bpf: add test for mixed signed and unsigned bounds checks
>   bpf/verifier: rework value tracking
>   nfp: change bpf verifier hooks to match new verifier data structures
>   bpf/verifier: track signed and unsigned min/max values
>   bpf/verifier: more concise register state logs for constant var_off
>   selftests/bpf: change test_verifier expectations
>   selftests/bpf: rewrite test_align
>   selftests/bpf: add a test to test_align
>   selftests/bpf: add test for bogus operations on pointers
>   selftests/bpf: don't try to access past MAX_PACKET_OFF in
> test_verifier
>   selftests/bpf: add tests for subtraction & negative numbers
>   selftests/bpf: variable offset negative tests
>
>  drivers/net/ethernet/netronome/nfp/bpf/verifier.c |   24 +-
>  include/linux/bpf.h   |   34 +-
>  include/linux/bpf_verifier.h  |   56 +-
>  include/linux/tnum.h  |   81 +
>  kernel/bpf/Makefile   |2 +-
>  kernel/bpf/tnum.c |  180 ++
>  kernel/bpf/verifier.c | 1943 
> -
>  tools/testing/selftests/bpf/test_align.c  |  462 -
>  tools/testing/selftests/bpf/test_verifier.c   |  293 ++--
>  9 files changed, 2034 insertions(+), 1041 deletions(-)
>  create mode 100644 include/linux/tnum.h
>  create mode 100644 kernel/bpf/tnum.c
>
> ___
> iovisor-dev mailing list
> iovisor-dev@lists.iovisor.org
> https://lists.iovisor.org/mailman/listinfo/iovisor-dev
___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev


Re: [iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-07-07 Thread Daniel Borkmann via iovisor-dev

On 07/07/2017 02:50 PM, Edward Cree wrote:

On 07/07/17 10:14, Daniel Borkmann wrote:

But this means the bpf_lxc_* cases increase quite significantly,
arguably one of them is pretty close already, but the other one not
so much, meaning while 142k would shoot over the 128k target quite a
bit, the 95k is quite close to the point that it wouldn't take much,
say, few different optimizations from compiler, to hit the limit as
well eventually, something like 156k for the time being would seem a
more adequate raise perhaps that needs to be evaluated carefully
given the situation.

Note that the numbers in my table are the _sum_ of all the progs in the
  object file, not the #insns for a single program.  (Hence the awk
  invocation in my pipeline.)  For instance in bpf_lxc_opt_-DUNKNOWN.o
  on net-next there were (iirc) a couple of 30k progs and then some
  smaller ones, not a single 93k prog.


Okay, sorry, seems I misread in that case.
___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev


Re: [iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-07-07 Thread Edward Cree via iovisor-dev
On 07/07/17 10:14, Daniel Borkmann wrote:
> But this means the bpf_lxc_* cases increase quite significantly,
> arguably one of them is pretty close already, but the other one not
> so much, meaning while 142k would shoot over the 128k target quite a
> bit, the 95k is quite close to the point that it wouldn't take much,
> say, few different optimizations from compiler, to hit the limit as
> well eventually, something like 156k for the time being would seem a
> more adequate raise perhaps that needs to be evaluated carefully
> given the situation.
Note that the numbers in my table are the _sum_ of all the progs in the
 object file, not the #insns for a single program.  (Hence the awk
 invocation in my pipeline.)  For instance in bpf_lxc_opt_-DUNKNOWN.o
 on net-next there were (iirc) a couple of 30k progs and then some
 smaller ones, not a single 93k prog.

-Ed
___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev


Re: [iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-07-07 Thread Daniel Borkmann via iovisor-dev

On 07/06/2017 08:27 PM, Edward Cree wrote:

On 04/07/17 23:28, Daniel Borkmann wrote:

Have you tried with cilium's BPF code? The kernel selftests are quite small,
so not really pushing processed insns too far. I can send you a BPF obj file
if that's easier for testing.

Results from the next (in-progress) version of the patch series, with the
  'id' bugfix I mentioned in my other mail, and rebased onto an updated
  net-next (0e72582).  Numbers collected with:
# tc filter add dev lo egress bpf da obj /path/to/bpf_object.o sec $section verb 2>&1 | 
grep "processed" | awk -e 'BEGIN { N = 0; }' -e '{ N += $2; }' -e 'END { print N; }'

Programnet-next   shortfull
bpf_lb_opt_-DLB_L3.o   470758726515
bpf_lb_opt_-DLB_L4.o   766286528976
bpf_lb_opt_-DUNKNOWN.o  72729722960
bpf_lxc_opt_-DDROP_ALL.o  57725   85750   95412
bpf_lxc_opt_-DUNKNOWN.o   93676  134043  141706
bpf_netdev.o  14702   24665   24251
bpf_overlay.o  7303   10939   10999

Conclusion: the ptr&const and full-range min/max tracking make little
  difference (10% increase at most, sometimes a decrease); most of the
  increase comes from the basic "replace imm and aux_off/align with tnums"
  patch.


Okay, thanks for the analysis, Edward.


So based on what Alexei was saying earlier, it sounds like the answer for
  now is to up the limit (say to a round 128k), get this series merged,
  then start work on pruning optimisation so we can hopefully bring that
  limit back down again later.  Sound reasonable?


But this means the bpf_lxc_* cases increase quite significantly,
arguably one of them is pretty close already, but the other one not
so much, meaning while 142k would shoot over the 128k target quite a
bit, the 95k is quite close to the point that it wouldn't take much,
say, few different optimizations from compiler, to hit the limit as
well eventually, something like 156k for the time being would seem a
more adequate raise perhaps that needs to be evaluated carefully
given the situation.
___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev


Re: [iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-07-06 Thread Edward Cree via iovisor-dev
On 04/07/17 23:28, Daniel Borkmann wrote:
> Have you tried with cilium's BPF code? The kernel selftests are quite small,
> so not really pushing processed insns too far. I can send you a BPF obj file
> if that's easier for testing.
Results from the next (in-progress) version of the patch series, with the
 'id' bugfix I mentioned in my other mail, and rebased onto an updated
 net-next (0e72582).  Numbers collected with:
# tc filter add dev lo egress bpf da obj /path/to/bpf_object.o sec $section 
verb 2>&1 | grep "processed" | awk -e 'BEGIN { N = 0; }' -e '{ N += $2; }' -e 
'END { print N; }'

Programnet-next   shortfull
bpf_lb_opt_-DLB_L3.o   470758726515
bpf_lb_opt_-DLB_L4.o   766286528976
bpf_lb_opt_-DUNKNOWN.o  72729722960
bpf_lxc_opt_-DDROP_ALL.o  57725   85750   95412
bpf_lxc_opt_-DUNKNOWN.o   93676  134043  141706
bpf_netdev.o  14702   24665   24251
bpf_overlay.o  7303   10939   10999

Conclusion: the ptr&const and full-range min/max tracking make little
 difference (10% increase at most, sometimes a decrease); most of the
 increase comes from the basic "replace imm and aux_off/align with tnums"
 patch.
So based on what Alexei was saying earlier, it sounds like the answer for
 now is to up the limit (say to a round 128k), get this series merged,
 then start work on pruning optimisation so we can hopefully bring that
 limit back down again later.  Sound reasonable?

-Ed
___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev


Re: [iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-07-06 Thread Edward Cree via iovisor-dev
On 04/07/17 20:22, Edward Cree wrote:
> I don't know why test_l4lb has to process _fewer_ insns with my patches;
>  if anything I'm worrying that I may be incorrectly pruning branches.
> (I've spotted a possible bug in that I'm not looking at 'id' which,
>  although it doesn't have to match, if two regs in the old state had the
>  same id as each other, then those regs in the new state have to have
>  the same id as each other too.)
I've now fixed that bug, and also changing it to not fill in 'id' on pointers
 other than PTR_TO_PACKET when doing arithmetic (because it's only used for
 'range' sharing and only PTR_TO_PACKET have that.  Of course
 PTR_TO_MAP_VALUE_OR_NULL still use id, but they don't get it from arithmetic).
Changes will be in next version of patch series, but for now:
Program net-next  short  full   new
test_pkt_access   78 797979
test_xdp 386411   407   389
test_l4lb   6438   4154  4154  4062
test_tcp_estats  435436   435   435
test_bpf_obj_id8  8 8 8
test_pkt_md_access41 424242
As you can see, the #insns has gone down even further.

-Ed
___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev


Re: [iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-07-04 Thread Daniel Borkmann via iovisor-dev

On 07/04/2017 09:22 PM, Edward Cree wrote:

On 30/06/17 19:15, Alexei Starovoitov wrote:

On 6/30/17 9:44 AM, Edward Cree wrote:

I haven't measured the test_progs ones, because I *still* haven't gotten
  around to actually setting up a BPF toolchain (it doesn't help that I'm
  building everything on a test server that gets reimaged every night to
  run our nightly tests...).


then you're missing a lot of tests then...
installing llvm is trivial. On x86 there are plenty of pre-built
packages that you can apt-get or yum.
Dave had to compile llvm and gcc from source on sparc, so volatile test
server isn't really an excuse to miss all these tests ;)
especially for such large verifier change.


After two days' wrestling with clang's build system, I'm finally able to
  run test_progs, and all its tests pass as of the full patch series.


(Hmm, usually with major distros LLVM comes with BPF targets enabled
by default these days, so there's less need to compile it from scratch
actually, just installation via yum/apt/... would suffice then.)


Here are the processed insn counts:

Program net-next  short  full
test_pkt_access   78 7979
test_xdp 386411   407
test_l4lb   6438   4154  4154
test_tcp_estats  435436   435
test_bpf_obj_id8  8 8
test_pkt_md_access41 4242

"short" is the first 3 patches plus the 'roll back ptr&const' patch I
  posted on Friday.  "full" is the full 12-patch series.  "Program" is
  the function in test_progs.c.
I don't know why test_l4lb has to process _fewer_ insns with my patches;
  if anything I'm worrying that I may be incorrectly pruning branches.
(I've spotted a possible bug in that I'm not looking at 'id' which,
  although it doesn't have to match, if two regs in the old state had the
  same id as each other, then those regs in the new state have to have
  the same id as each other too.)
Also interesting is that going from "short" to "full" only decreases the
  counts, suggesting that the ptr&const and full negative/positive
  tracking isn't (at least for these test cases) costly.


Have you tried with cilium's BPF code? The kernel selftests are quite small,
so not really pushing processed insns too far. I can send you a BPF obj file
if that's easier for testing.

Thanks,
Daniel
___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev


Re: [iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-07-04 Thread Edward Cree via iovisor-dev
On 30/06/17 19:15, Alexei Starovoitov wrote:
> On 6/30/17 9:44 AM, Edward Cree wrote:
>> I haven't measured the test_progs ones, because I *still* haven't gotten
>>  around to actually setting up a BPF toolchain (it doesn't help that I'm
>>  building everything on a test server that gets reimaged every night to
>>  run our nightly tests...).
>
> then you're missing a lot of tests then...
> installing llvm is trivial. On x86 there are plenty of pre-built
> packages that you can apt-get or yum.
> Dave had to compile llvm and gcc from source on sparc, so volatile test
> server isn't really an excuse to miss all these tests ;)
> especially for such large verifier change.
>
After two days' wrestling with clang's build system, I'm finally able to
 run test_progs, and all its tests pass as of the full patch series.
Here are the processed insn counts:

Program net-next  short  full
test_pkt_access   78 7979
test_xdp 386411   407
test_l4lb   6438   4154  4154
test_tcp_estats  435436   435
test_bpf_obj_id8  8 8
test_pkt_md_access41 4242

"short" is the first 3 patches plus the 'roll back ptr&const' patch I
 posted on Friday.  "full" is the full 12-patch series.  "Program" is
 the function in test_progs.c.
I don't know why test_l4lb has to process _fewer_ insns with my patches;
 if anything I'm worrying that I may be incorrectly pruning branches.
(I've spotted a possible bug in that I'm not looking at 'id' which,
 although it doesn't have to match, if two regs in the old state had the
 same id as each other, then those regs in the new state have to have
 the same id as each other too.)
Also interesting is that going from "short" to "full" only decreases the
 counts, suggesting that the ptr&const and full negative/positive
 tracking isn't (at least for these test cases) costly.

-Ed
___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev


Re: [iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-06-30 Thread Alexei Starovoitov via iovisor-dev

On 6/30/17 9:44 AM, Edward Cree wrote:

I haven't measured the test_progs ones, because I *still* haven't gotten
 around to actually setting up a BPF toolchain (it doesn't help that I'm
 building everything on a test server that gets reimaged every night to
 run our nightly tests...).


then you're missing a lot of tests then...
installing llvm is trivial. On x86 there are plenty of pre-built
packages that you can apt-get or yum.
Dave had to compile llvm and gcc from source on sparc, so volatile test
server isn't really an excuse to miss all these tests ;)
especially for such large verifier change.

___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev


Re: [iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-06-30 Thread Edward Cree via iovisor-dev
On 28/06/17 22:37, Alexei Starovoitov wrote:
> Increasing the limit is must have, since pruning suffered so much.
> Going from 53k to 76k is pretty substantial.
> What is the % increase for tests in selftests/ ?
When I tried to measure the test_verifier tests, they changed hardly at
 all, only a couple of percent iirc.  But that's with (a) only the
 accepted progs get measured, since rejected don't print the #insns line
 - and most of the tests in test_verifier are rejected; and (b) those
 test progs are pretty small, usually with only a couple of jumps and
 not much chance for pruning to occur.  So it's really not a great test
 case for pruning effectiveness.
I haven't measured the test_progs ones, because I *still* haven't gotten
 around to actually setting up a BPF toolchain (it doesn't help that I'm
 building everything on a test server that gets reimaged every night to
 run our nightly tests...).
> I think we need to pin point exactly the reason.
> Saying we just track more data is not enough.
> We've tried v2 set on our load balancer and also saw ~20% increase.
> I don't remember the absolute numbers.
> These jumps don't make me comfortable with these extra tracking.
> Can you try to roll back ptr&const and full negative/positive tracking
> and see whether it gets back to what we had before?
The ptr&const bit shouldn't be relevant unless your programs are actually
 doing that (i.e. ops on pointers other than +/-), which seems surprising.
 But if you really are, then it's not too hard to roll it back - just
 need to change how adjust_reg_min_max_vals() deals with EACCES.
For a version without full negative/positive tracking, just take the first
 3 patches; some of the selftests will fail but hopefully your progs will
 still be accepted.  If not, we can try jbacik's patch (off-list response
 to v2).  I will followup this email with a patch to apply on top of the
 first 3 that does that and rolls back ptr&const.
> If tnum is causing it that would be reasonable trade off to make,
> but if it's full neg/pos tracking that has no use today other than
> (the whole thing is cleaner) I would rather drop it then.
Well, the full neg/pos tracking was a result of needing to fix the bug I
 found with patch #1, and not wanting to confuse myself with the min/max
 range while doing my signed/unsigned tracking.  But if we can make it
 work with jbacik's approach of 'remember whether our current bounds came
 from a signed or an unsigned compare', then we can drop or delay the
 full neg/pos tracking unless/until pruning is sorted out.

-Ed
___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev


Re: [iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-06-28 Thread Alexei Starovoitov via iovisor-dev
On Wed, Jun 28, 2017 at 10:38:02PM +0200, Daniel Borkmann wrote:
> On 06/28/2017 04:11 PM, Edward Cree wrote:
> > On 28/06/17 14:50, Daniel Borkmann wrote:
> > > Hi Edward,
> > > 
> > > Did you also have a chance in the meantime to look at reducing complexity
> > > along with your unification? I did run the cilium test suite with your
> > > latest set from here and current # worst case processed insns that
> > > verifier has to go through for cilium progs increases from ~53k we have
> > > right now to ~76k. I'm a bit worried that this quickly gets us close to
> > > the upper ~98k max limit starting to reject programs again. Alternative
> > > is to bump the complexity limit again in near future once run into it,
> > > but preferably there's a way to optimize it along with the rewrite? Do
> > > you see any possibilities worth exploring?
> > The trouble, I think, is that as we're now tracking more information about
> >   each register value, we're less able to prune branches.  But often that
> >   information is not actually being used in reaching the exit state.  So it
> 
> Agree.
> 
> >   seems like the way to tackle this would be to track what information is
> >   used — or at least, which registers are read from (including e.g. writing
> >   through them or passing them to helper calls) — in reaching a safe state.
> >   Then only registers which are used are required to match for pruning.
> > But that tracking would presumably have to propagate backwards through the
> >   verifier stack, and I'm not sure how easily that could be done.  Someone
> >   (was it you?) was talking about replacing the current DAG walking and
> >   pruning with some kind of basic-block thing, which would help with this.
> > Summary: I think it could be done, but I haven't looked into the details
> >   of implementation yet; if it's not actually breaking your programs (yet),
> >   maybe leave it for a followup patch series?
> 
> Could we adapt the limit to 128k perhaps as part of this set
> given we know that we're tracking more meta data here anyway?

Increasing the limit is must have, since pruning suffered so much.
Going from 53k to 76k is pretty substantial.
What is the % increase for tests in selftests/ ?
I think we need to pin point exactly the reason.
Saying we just track more data is not enough.
We've tried v2 set on our load balancer and also saw ~20% increase.
I don't remember the absolute numbers.
These jumps don't make me comfortable with these extra tracking.
Can you try to roll back ptr&const and full negative/positive tracking
and see whether it gets back to what we had before?
I agree that long term it's better to do proper basic block based
liveness, but we need to do understand what's causing the increase today.
If tnum is causing it that would be reasonable trade off to make,
but if it's full neg/pos tracking that has no use today other than
(the whole thing is cleaner) I would rather drop it then.
We can always come back to it later once pruning issues are solved.

___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev


Re: [iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-06-28 Thread Daniel Borkmann via iovisor-dev

On 06/28/2017 04:11 PM, Edward Cree wrote:

On 28/06/17 14:50, Daniel Borkmann wrote:

Hi Edward,

Did you also have a chance in the meantime to look at reducing complexity
along with your unification? I did run the cilium test suite with your
latest set from here and current # worst case processed insns that
verifier has to go through for cilium progs increases from ~53k we have
right now to ~76k. I'm a bit worried that this quickly gets us close to
the upper ~98k max limit starting to reject programs again. Alternative
is to bump the complexity limit again in near future once run into it,
but preferably there's a way to optimize it along with the rewrite? Do
you see any possibilities worth exploring?

The trouble, I think, is that as we're now tracking more information about
  each register value, we're less able to prune branches.  But often that
  information is not actually being used in reaching the exit state.  So it


Agree.


  seems like the way to tackle this would be to track what information is
  used — or at least, which registers are read from (including e.g. writing
  through them or passing them to helper calls) — in reaching a safe state.
  Then only registers which are used are required to match for pruning.
But that tracking would presumably have to propagate backwards through the
  verifier stack, and I'm not sure how easily that could be done.  Someone
  (was it you?) was talking about replacing the current DAG walking and
  pruning with some kind of basic-block thing, which would help with this.
Summary: I think it could be done, but I haven't looked into the details
  of implementation yet; if it's not actually breaking your programs (yet),
  maybe leave it for a followup patch series?


Could we adapt the limit to 128k perhaps as part of this set
given we know that we're tracking more meta data here anyway?
Then we could potentially avoid going via -stable later on,
biggest pain point is usually tracking differences in LLVM
code generation (e.g. differences in optimizations) along with
verifier changes to make sure that programs still keep loading
on older kernels with e.g. newer LLVM; one of the issues is that
pruning can be quite fragile. E.g. worst case adding a simple
var in a branch that LLVM assigns a stack slot that was otherwise
not used throughout the prog can cause a significant increase of
verifier work (run into this multiple times in the past and
is a bit of a pain to track down actually). If we could keep
some buffer in BPF_COMPLEXITY_LIMIT_INSNS at least when we know
that more work is needed anyway from that point onward, that
would be good.
___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev


Re: [iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-06-28 Thread Edward Cree via iovisor-dev
On 28/06/17 14:50, Daniel Borkmann wrote:
> Hi Edward,
>
> Did you also have a chance in the meantime to look at reducing complexity
> along with your unification? I did run the cilium test suite with your
> latest set from here and current # worst case processed insns that
> verifier has to go through for cilium progs increases from ~53k we have
> right now to ~76k. I'm a bit worried that this quickly gets us close to
> the upper ~98k max limit starting to reject programs again. Alternative
> is to bump the complexity limit again in near future once run into it,
> but preferably there's a way to optimize it along with the rewrite? Do
> you see any possibilities worth exploring? 
The trouble, I think, is that as we're now tracking more information about
 each register value, we're less able to prune branches.  But often that
 information is not actually being used in reaching the exit state.  So it
 seems like the way to tackle this would be to track what information is
 used — or at least, which registers are read from (including e.g. writing
 through them or passing them to helper calls) — in reaching a safe state.
 Then only registers which are used are required to match for pruning.
But that tracking would presumably have to propagate backwards through the
 verifier stack, and I'm not sure how easily that could be done.  Someone
 (was it you?) was talking about replacing the current DAG walking and
 pruning with some kind of basic-block thing, which would help with this.
Summary: I think it could be done, but I haven't looked into the details
 of implementation yet; if it's not actually breaking your programs (yet),
 maybe leave it for a followup patch series?

-Ed
___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev


Re: [iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-06-28 Thread Daniel Borkmann via iovisor-dev

Hi Edward,

On 06/27/2017 02:53 PM, Edward Cree wrote:

This series simplifies alignment tracking, generalises bounds tracking and
  fixes some bounds-tracking bugs in the BPF verifier.  Pointer arithmetic on
  packet pointers, stack pointers, map value pointers and context pointers has
  been unified, and bounds on these pointers are only checked when the pointer
  is dereferenced.
Operations on pointers which destroy all relation to the original pointer
  (such as multiplies and shifts) are disallowed if !env->allow_ptr_leaks,
  otherwise they convert the pointer to an unknown scalar and feed it to the
  normal scalar arithmetic handling.
Pointer types have been unified with the corresponding adjusted-pointer types
  where those existed (e.g. PTR_TO_MAP_VALUE[_ADJ] or FRAME_PTR vs
  PTR_TO_STACK); similarly, CONST_IMM and UNKNOWN_VALUE have been unified into
  SCALAR_VALUE.
Pointer types (except CONST_PTR_TO_MAP, PTR_TO_MAP_VALUE_OR_NULL and
  PTR_TO_PACKET_END, which do not allow arithmetic) have a 'fixed offset' and
  a 'variable offset'; the former is used when e.g. adding an immediate or a
  known-constant register, as long as it does not overflow.  Otherwise the
  latter is used, and any operation creating a new variable offset creates a
  new 'id' (and, for PTR_TO_PACKET, clears the 'range').
SCALAR_VALUEs use the 'variable offset' fields to track the range of possible
  values; the 'fixed offset' should never be set on a scalar.

As of patch 12/12, all tests of tools/testing/selftests/bpf/test_verifier
  and tools/testing/selftests/bpf/test_align pass.

v3: added a few more tests; removed RFC tags.


Did you also have a chance in the meantime to look at reducing complexity
along with your unification? I did run the cilium test suite with your
latest set from here and current # worst case processed insns that
verifier has to go through for cilium progs increases from ~53k we have
right now to ~76k. I'm a bit worried that this quickly gets us close to
the upper ~98k max limit starting to reject programs again. Alternative
is to bump the complexity limit again in near future once run into it,
but preferably there's a way to optimize it along with the rewrite? Do
you see any possibilities worth exploring?


v2: fixed nfp build, made test_align pass again and extended it with a few
  new tests (though still need to add more).

Edward Cree (12):
   selftests/bpf: add test for mixed signed and unsigned bounds checks
   bpf/verifier: rework value tracking
   nfp: change bpf verifier hooks to match new verifier data structures
   bpf/verifier: track signed and unsigned min/max values
   bpf/verifier: more concise register state logs for constant var_off
   selftests/bpf: change test_verifier expectations
   selftests/bpf: rewrite test_align
   selftests/bpf: add a test to test_align
   selftests/bpf: add test for bogus operations on pointers
   selftests/bpf: don't try to access past MAX_PACKET_OFF in
 test_verifier
   selftests/bpf: add tests for subtraction & negative numbers
   selftests/bpf: variable offset negative tests

  drivers/net/ethernet/netronome/nfp/bpf/verifier.c |   24 +-
  include/linux/bpf.h   |   34 +-
  include/linux/bpf_verifier.h  |   56 +-
  include/linux/tnum.h  |   81 +
  kernel/bpf/Makefile   |2 +-
  kernel/bpf/tnum.c |  180 ++
  kernel/bpf/verifier.c | 1943 -
  tools/testing/selftests/bpf/test_align.c  |  462 -
  tools/testing/selftests/bpf/test_verifier.c   |  293 ++--
  9 files changed, 2034 insertions(+), 1041 deletions(-)
  create mode 100644 include/linux/tnum.h
  create mode 100644 kernel/bpf/tnum.c



Thanks,
Daniel
___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev


[iovisor-dev] [PATCH v3 net-next 00/12] bpf: rewrite value tracking in verifier

2017-06-27 Thread Edward Cree via iovisor-dev
This series simplifies alignment tracking, generalises bounds tracking and
 fixes some bounds-tracking bugs in the BPF verifier.  Pointer arithmetic on
 packet pointers, stack pointers, map value pointers and context pointers has
 been unified, and bounds on these pointers are only checked when the pointer
 is dereferenced.
Operations on pointers which destroy all relation to the original pointer
 (such as multiplies and shifts) are disallowed if !env->allow_ptr_leaks,
 otherwise they convert the pointer to an unknown scalar and feed it to the
 normal scalar arithmetic handling.
Pointer types have been unified with the corresponding adjusted-pointer types
 where those existed (e.g. PTR_TO_MAP_VALUE[_ADJ] or FRAME_PTR vs
 PTR_TO_STACK); similarly, CONST_IMM and UNKNOWN_VALUE have been unified into
 SCALAR_VALUE.
Pointer types (except CONST_PTR_TO_MAP, PTR_TO_MAP_VALUE_OR_NULL and
 PTR_TO_PACKET_END, which do not allow arithmetic) have a 'fixed offset' and
 a 'variable offset'; the former is used when e.g. adding an immediate or a
 known-constant register, as long as it does not overflow.  Otherwise the
 latter is used, and any operation creating a new variable offset creates a
 new 'id' (and, for PTR_TO_PACKET, clears the 'range').
SCALAR_VALUEs use the 'variable offset' fields to track the range of possible
 values; the 'fixed offset' should never be set on a scalar.

As of patch 12/12, all tests of tools/testing/selftests/bpf/test_verifier
 and tools/testing/selftests/bpf/test_align pass.

v3: added a few more tests; removed RFC tags.

v2: fixed nfp build, made test_align pass again and extended it with a few
 new tests (though still need to add more).

Edward Cree (12):
  selftests/bpf: add test for mixed signed and unsigned bounds checks
  bpf/verifier: rework value tracking
  nfp: change bpf verifier hooks to match new verifier data structures
  bpf/verifier: track signed and unsigned min/max values
  bpf/verifier: more concise register state logs for constant var_off
  selftests/bpf: change test_verifier expectations
  selftests/bpf: rewrite test_align
  selftests/bpf: add a test to test_align
  selftests/bpf: add test for bogus operations on pointers
  selftests/bpf: don't try to access past MAX_PACKET_OFF in
test_verifier
  selftests/bpf: add tests for subtraction & negative numbers
  selftests/bpf: variable offset negative tests

 drivers/net/ethernet/netronome/nfp/bpf/verifier.c |   24 +-
 include/linux/bpf.h   |   34 +-
 include/linux/bpf_verifier.h  |   56 +-
 include/linux/tnum.h  |   81 +
 kernel/bpf/Makefile   |2 +-
 kernel/bpf/tnum.c |  180 ++
 kernel/bpf/verifier.c | 1943 -
 tools/testing/selftests/bpf/test_align.c  |  462 -
 tools/testing/selftests/bpf/test_verifier.c   |  293 ++--
 9 files changed, 2034 insertions(+), 1041 deletions(-)
 create mode 100644 include/linux/tnum.h
 create mode 100644 kernel/bpf/tnum.c

___
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev