diff mbox series

[bpf,2/2] bpf: selftest to verify mixing bpf2bpf calls and tailcalls with insn patch

Message ID 162318063321.323820.18256758193426055338.stgit@john-XPS-13-9370
State New
Headers show
Series [bpf,1/2] bpf: Fix null ptr deref with mixed tail calls and subprogs | expand

Commit Message

John Fastabend June 8, 2021, 7:30 p.m. UTC
This adds some extra noise to the tailcall_bpf2bpf4 tests that will cause
verifier to patch insns. This then moves around subprog start/end insn
index and poke descriptor insn index to ensure that verify and JIT will
continue to track these correctly.

Reviewed-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
 .../selftests/bpf/progs/tailcall_bpf2bpf4.c        |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

Comments

Yonghong Song June 9, 2021, 6:22 a.m. UTC | #1
On 6/8/21 12:30 PM, John Fastabend wrote:
> This adds some extra noise to the tailcall_bpf2bpf4 tests that will cause

> verifier to patch insns. This then moves around subprog start/end insn

> index and poke descriptor insn index to ensure that verify and JIT will

> continue to track these correctly.

> 

> Reviewed-by: Daniel Borkmann <daniel@iogearbox.net>

> Signed-off-by: John Fastabend <john.fastabend@gmail.com>


Acked-by: Yonghong Song <yhs@fb.com>
Maciej Fijalkowski June 9, 2021, 3:57 p.m. UTC | #2
On Tue, Jun 08, 2021 at 12:30:33PM -0700, John Fastabend wrote:
> This adds some extra noise to the tailcall_bpf2bpf4 tests that will cause

> verifier to patch insns. This then moves around subprog start/end insn

> index and poke descriptor insn index to ensure that verify and JIT will

> continue to track these correctly.


This test is the most complicated one where I tried to document the scope
of it on the side of prog_tests/tailcalls.c. I feel that it would make it
more difficult to debug it if under any circumstances something would have
been broken with that logic.

Maybe a separate test scenario? Or is this an overkill? If so, I would
vote for moving it to tailcall_bpf2bpf1.c and have a little comment that
testing other bpf helpers mixed in is in scope of that test.

> 

> Reviewed-by: Daniel Borkmann <daniel@iogearbox.net>

> Signed-off-by: John Fastabend <john.fastabend@gmail.com>

> ---

>  .../selftests/bpf/progs/tailcall_bpf2bpf4.c        |   17 +++++++++++++++++

>  1 file changed, 17 insertions(+)

> 

> diff --git a/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c b/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c

> index 9a1b166b7fbe..0d70de5f97e2 100644

> --- a/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c

> +++ b/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c

> @@ -2,6 +2,13 @@

>  #include <linux/bpf.h>

>  #include <bpf/bpf_helpers.h>

>  

> +struct {

> +	__uint(type, BPF_MAP_TYPE_ARRAY);

> +	__uint(max_entries, 1);

> +	__uint(key_size, sizeof(__u32));

> +	__uint(value_size, sizeof(__u32));

> +} nop_table SEC(".maps");

> +

>  struct {

>  	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);

>  	__uint(max_entries, 3);

> @@ -11,9 +18,19 @@ struct {

>  

>  static volatile int count;

>  

> +__noinline

> +int subprog_noise(struct __sk_buff *skb)

> +{

> +	__u32 key = 0;

> +

> +	bpf_map_lookup_elem(&nop_table, &key);

> +	return 0;

> +}

> +

>  __noinline

>  int subprog_tail_2(struct __sk_buff *skb)

>  {

> +	subprog_noise(skb);

>  	bpf_tail_call_static(skb, &jmp_table, 2);

>  	return skb->len * 3;

>  }

> 

>
Maciej Fijalkowski June 9, 2021, 4:21 p.m. UTC | #3
On Wed, Jun 09, 2021 at 09:26:01AM -0700, John Fastabend wrote:
> Maciej Fijalkowski wrote:

> > On Tue, Jun 08, 2021 at 12:30:33PM -0700, John Fastabend wrote:

> > > This adds some extra noise to the tailcall_bpf2bpf4 tests that will cause

> > > verifier to patch insns. This then moves around subprog start/end insn

> > > index and poke descriptor insn index to ensure that verify and JIT will

> > > continue to track these correctly.

> > 

> > This test is the most complicated one where I tried to document the scope

> > of it on the side of prog_tests/tailcalls.c. I feel that it would make it

> > more difficult to debug it if under any circumstances something would have

> > been broken with that logic.

> > 

> > Maybe a separate test scenario? Or is this an overkill? If so, I would

> > vote for moving it to tailcall_bpf2bpf1.c and have a little comment that

> > testing other bpf helpers mixed in is in scope of that test.

> 

> I like pushing it into the complex test to get the most instruction

> patching combinations possible.


Makes sense after a second thought, that was the intention of that test
case, to squeeze out the feature out here.

I still would ask to have it commented on the prog_tests/tailcalls.c side,
WDYT?

> 

> > 

> > > 

> > > Reviewed-by: Daniel Borkmann <daniel@iogearbox.net>

> > > Signed-off-by: John Fastabend <john.fastabend@gmail.com>

> > > ---

> > >  .../selftests/bpf/progs/tailcall_bpf2bpf4.c        |   17 +++++++++++++++++

> > >  1 file changed, 17 insertions(+)

> > > 

> > > diff --git a/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c b/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c

> > > index 9a1b166b7fbe..0d70de5f97e2 100644

> > > --- a/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c

> > > +++ b/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c

> > > @@ -2,6 +2,13 @@

> > >  #include <linux/bpf.h>

> > >  #include <bpf/bpf_helpers.h>

> > >  

> > > +struct {

> > > +	__uint(type, BPF_MAP_TYPE_ARRAY);

> > > +	__uint(max_entries, 1);

> > > +	__uint(key_size, sizeof(__u32));

> > > +	__uint(value_size, sizeof(__u32));

> > > +} nop_table SEC(".maps");

> > > +

> > >  struct {

> > >  	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);

> > >  	__uint(max_entries, 3);

> > > @@ -11,9 +18,19 @@ struct {

> > >  

> > >  static volatile int count;

> > >  

> > > +__noinline

> > > +int subprog_noise(struct __sk_buff *skb)

> > > +{

> > > +	__u32 key = 0;

> > > +

> > > +	bpf_map_lookup_elem(&nop_table, &key);

> > > +	return 0;

> > > +}

> > > +

> > >  __noinline

> > >  int subprog_tail_2(struct __sk_buff *skb)

> > >  {

> > > +	subprog_noise(skb);

> > >  	bpf_tail_call_static(skb, &jmp_table, 2);

> > >  	return skb->len * 3;

> > >  }

> > > 

> > > 

> 

>
John Fastabend June 9, 2021, 4:26 p.m. UTC | #4
Maciej Fijalkowski wrote:
> On Tue, Jun 08, 2021 at 12:30:33PM -0700, John Fastabend wrote:

> > This adds some extra noise to the tailcall_bpf2bpf4 tests that will cause

> > verifier to patch insns. This then moves around subprog start/end insn

> > index and poke descriptor insn index to ensure that verify and JIT will

> > continue to track these correctly.

> 

> This test is the most complicated one where I tried to document the scope

> of it on the side of prog_tests/tailcalls.c. I feel that it would make it

> more difficult to debug it if under any circumstances something would have

> been broken with that logic.

> 

> Maybe a separate test scenario? Or is this an overkill? If so, I would

> vote for moving it to tailcall_bpf2bpf1.c and have a little comment that

> testing other bpf helpers mixed in is in scope of that test.


I like pushing it into the complex test to get the most instruction
patching combinations possible.

> 

> > 

> > Reviewed-by: Daniel Borkmann <daniel@iogearbox.net>

> > Signed-off-by: John Fastabend <john.fastabend@gmail.com>

> > ---

> >  .../selftests/bpf/progs/tailcall_bpf2bpf4.c        |   17 +++++++++++++++++

> >  1 file changed, 17 insertions(+)

> > 

> > diff --git a/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c b/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c

> > index 9a1b166b7fbe..0d70de5f97e2 100644

> > --- a/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c

> > +++ b/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c

> > @@ -2,6 +2,13 @@

> >  #include <linux/bpf.h>

> >  #include <bpf/bpf_helpers.h>

> >  

> > +struct {

> > +	__uint(type, BPF_MAP_TYPE_ARRAY);

> > +	__uint(max_entries, 1);

> > +	__uint(key_size, sizeof(__u32));

> > +	__uint(value_size, sizeof(__u32));

> > +} nop_table SEC(".maps");

> > +

> >  struct {

> >  	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);

> >  	__uint(max_entries, 3);

> > @@ -11,9 +18,19 @@ struct {

> >  

> >  static volatile int count;

> >  

> > +__noinline

> > +int subprog_noise(struct __sk_buff *skb)

> > +{

> > +	__u32 key = 0;

> > +

> > +	bpf_map_lookup_elem(&nop_table, &key);

> > +	return 0;

> > +}

> > +

> >  __noinline

> >  int subprog_tail_2(struct __sk_buff *skb)

> >  {

> > +	subprog_noise(skb);

> >  	bpf_tail_call_static(skb, &jmp_table, 2);

> >  	return skb->len * 3;

> >  }

> > 

> >
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c b/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c
index 9a1b166b7fbe..0d70de5f97e2 100644
--- a/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c
+++ b/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c
@@ -2,6 +2,13 @@ 
 #include <linux/bpf.h>
 #include <bpf/bpf_helpers.h>
 
+struct {
+	__uint(type, BPF_MAP_TYPE_ARRAY);
+	__uint(max_entries, 1);
+	__uint(key_size, sizeof(__u32));
+	__uint(value_size, sizeof(__u32));
+} nop_table SEC(".maps");
+
 struct {
 	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
 	__uint(max_entries, 3);
@@ -11,9 +18,19 @@  struct {
 
 static volatile int count;
 
+__noinline
+int subprog_noise(struct __sk_buff *skb)
+{
+	__u32 key = 0;
+
+	bpf_map_lookup_elem(&nop_table, &key);
+	return 0;
+}
+
 __noinline
 int subprog_tail_2(struct __sk_buff *skb)
 {
+	subprog_noise(skb);
 	bpf_tail_call_static(skb, &jmp_table, 2);
 	return skb->len * 3;
 }