diff mbox series

[bpf-next,2/2] selftests/bpf: Add selftest for allow_ptr_leaks

Message ID 20230818083920.3771-3-laoar.shao@gmail.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series bpf: Fix an issue in verifing allow_ptr_leaks | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 9 this patch: 9
netdev/cc_maintainers warning 4 maintainers not CCed: shuah@kernel.org mykolal@fb.com iii@linux.ibm.com linux-kselftest@vger.kernel.org
netdev/build_clang success Errors and warnings before: 9 this patch: 9
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 9 this patch: 9
netdev/checkpatch warning WARNING: line length of 83 exceeds 80 columns WARNING: line length of 87 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-29 success Logs for veristat
bpf/vmtest-bpf-next-PR fail PR summary
bpf/vmtest-bpf-next-VM_Test-17 success Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-7 fail Logs for test_maps on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-2 success Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-8 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-21 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-10 success Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 success Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-15 success Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-28 success Logs for veristat
bpf/vmtest-bpf-next-VM_Test-25 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-26 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 success Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-11 success Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-1 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-4 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-0 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-5 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for x86_64 with gcc

Commit Message

Yafang Shao Aug. 18, 2023, 8:39 a.m. UTC
- Without prev commit

  $ tools/testing/selftests/bpf/test_progs --name=tc_bpf
  #232/1   tc_bpf/tc_bpf_root:OK
  test_tc_bpf_non_root:PASS:set_cap_bpf_cap_net_admin 0 nsec
  test_tc_bpf_non_root:PASS:disable_cap_sys_admin 0 nsec
  0: R1=ctx(off=0,imm=0) R10=fp0
  ; if ((long)(iph + 1) > (long)skb->data_end)
  0: (61) r2 = *(u32 *)(r1 +80)         ; R1=ctx(off=0,imm=0) R2_w=pkt_end(off=0,imm=0)
  ; struct iphdr *iph = (void *)(long)skb->data + sizeof(struct ethhdr);
  1: (61) r1 = *(u32 *)(r1 +76)         ; R1_w=pkt(off=0,r=0,imm=0)
  ; if ((long)(iph + 1) > (long)skb->data_end)
  2: (07) r1 += 34                      ; R1_w=pkt(off=34,r=0,imm=0)
  3: (b4) w0 = 1                        ; R0_w=1
  4: (2d) if r1 > r2 goto pc+1
  R2 pointer comparison prohibited
  processed 5 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
  test_tc_bpf_non_root:FAIL:test_tc_bpf__open_and_load unexpected error: -13
  #233/2   tc_bpf_non_root:FAIL

- With prev commit

  $ tools/testing/selftests/bpf/test_progs --name=tc_bpf
  #232/1   tc_bpf/tc_bpf_root:OK
  #232/2   tc_bpf/tc_bpf_non_root:OK
  #232     tc_bpf:OK
  Summary: 1/2 PASSED, 0 SKIPPED, 0 FAILED

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 tools/testing/selftests/bpf/prog_tests/tc_bpf.c | 36 ++++++++++++++++++++++++-
 tools/testing/selftests/bpf/progs/test_tc_bpf.c | 14 ++++++++++
 2 files changed, 49 insertions(+), 1 deletion(-)

Comments

Alexei Starovoitov Aug. 21, 2023, 10:45 p.m. UTC | #1
On Fri, Aug 18, 2023 at 1:39 AM Yafang Shao <laoar.shao@gmail.com> wrote:
>
> - Without prev commit
>
>   $ tools/testing/selftests/bpf/test_progs --name=tc_bpf
>   #232/1   tc_bpf/tc_bpf_root:OK
>   test_tc_bpf_non_root:PASS:set_cap_bpf_cap_net_admin 0 nsec
>   test_tc_bpf_non_root:PASS:disable_cap_sys_admin 0 nsec
>   0: R1=ctx(off=0,imm=0) R10=fp0
>   ; if ((long)(iph + 1) > (long)skb->data_end)
>   0: (61) r2 = *(u32 *)(r1 +80)         ; R1=ctx(off=0,imm=0) R2_w=pkt_end(off=0,imm=0)
>   ; struct iphdr *iph = (void *)(long)skb->data + sizeof(struct ethhdr);
>   1: (61) r1 = *(u32 *)(r1 +76)         ; R1_w=pkt(off=0,r=0,imm=0)
>   ; if ((long)(iph + 1) > (long)skb->data_end)
>   2: (07) r1 += 34                      ; R1_w=pkt(off=34,r=0,imm=0)
>   3: (b4) w0 = 1                        ; R0_w=1
>   4: (2d) if r1 > r2 goto pc+1
>   R2 pointer comparison prohibited
>   processed 5 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
>   test_tc_bpf_non_root:FAIL:test_tc_bpf__open_and_load unexpected error: -13
>   #233/2   tc_bpf_non_root:FAIL
>
> - With prev commit
>
>   $ tools/testing/selftests/bpf/test_progs --name=tc_bpf
>   #232/1   tc_bpf/tc_bpf_root:OK
>   #232/2   tc_bpf/tc_bpf_non_root:OK
>   #232     tc_bpf:OK
>   Summary: 1/2 PASSED, 0 SKIPPED, 0 FAILED
>
> Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> ---
>  tools/testing/selftests/bpf/prog_tests/tc_bpf.c | 36 ++++++++++++++++++++++++-
>  tools/testing/selftests/bpf/progs/test_tc_bpf.c | 14 ++++++++++
>  2 files changed, 49 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/selftests/bpf/prog_tests/tc_bpf.c b/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
> index e873766..48b5553 100644
> --- a/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
> +++ b/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
> @@ -3,6 +3,7 @@
>  #include <test_progs.h>
>  #include <linux/pkt_cls.h>
>
> +#include "cap_helpers.h"
>  #include "test_tc_bpf.skel.h"
>
>  #define LO_IFINDEX 1
> @@ -327,7 +328,7 @@ static int test_tc_bpf_api(struct bpf_tc_hook *hook, int fd)
>         return 0;
>  }
>
> -void test_tc_bpf(void)
> +void tc_bpf_root(void)
>  {
>         DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .ifindex = LO_IFINDEX,
>                             .attach_point = BPF_TC_INGRESS);
> @@ -393,3 +394,36 @@ void test_tc_bpf(void)
>         }
>         test_tc_bpf__destroy(skel);
>  }
> +
> +void tc_bpf_non_root(void)
> +{
> +       struct test_tc_bpf *skel = NULL;
> +       __u64 caps = 0;
> +       int ret;
> +
> +       /* In case CAP_BPF and CAP_PERFMON is not set */
> +       ret = cap_enable_effective(1ULL << CAP_BPF | 1ULL << CAP_NET_ADMIN, &caps);
> +       if (!ASSERT_OK(ret, "set_cap_bpf_cap_net_admin"))
> +               return;
> +       ret = cap_disable_effective(1ULL << CAP_SYS_ADMIN | 1ULL << CAP_PERFMON, NULL);
> +       if (!ASSERT_OK(ret, "disable_cap_sys_admin"))
> +               goto restore_cap;
> +
> +       skel = test_tc_bpf__open_and_load();
> +       if (!ASSERT_OK_PTR(skel, "test_tc_bpf__open_and_load"))
> +               goto restore_cap;
> +
> +       test_tc_bpf__destroy(skel);
> +
> +restore_cap:
> +       if (caps)
> +               cap_enable_effective(caps, NULL);
> +}
> +
> +void test_tc_bpf(void)
> +{
> +       if (test__start_subtest("tc_bpf_root"))
> +               tc_bpf_root();
> +       if (test__start_subtest("tc_bpf_non_root"))
> +               tc_bpf_non_root();
> +}
> diff --git a/tools/testing/selftests/bpf/progs/test_tc_bpf.c b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> index d28ca8d..3e0f218 100644
> --- a/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> +++ b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> @@ -1,5 +1,8 @@
>  // SPDX-License-Identifier: GPL-2.0
>
> +#include <linux/pkt_cls.h>
> +#include <linux/ip.h>
> +#include <linux/if_ether.h>

Due to above it fails to compile:

In file included from progs/test_tc_bpf.c:4:
In file included from /usr/include/linux/ip.h:21:
In file included from /usr/include/asm/byteorder.h:5:
In file included from /usr/include/linux/byteorder/little_endian.h:13:
/usr/include/linux/swab.h:136:8: error: unknown type name '__always_inline'
  136 | static __always_inline unsigned long __swab(const unsigned long y)
      |        ^
Yafang Shao Aug. 22, 2023, 2:42 a.m. UTC | #2
On Tue, Aug 22, 2023 at 6:45 AM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Fri, Aug 18, 2023 at 1:39 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> >
> > - Without prev commit
> >
> >   $ tools/testing/selftests/bpf/test_progs --name=tc_bpf
> >   #232/1   tc_bpf/tc_bpf_root:OK
> >   test_tc_bpf_non_root:PASS:set_cap_bpf_cap_net_admin 0 nsec
> >   test_tc_bpf_non_root:PASS:disable_cap_sys_admin 0 nsec
> >   0: R1=ctx(off=0,imm=0) R10=fp0
> >   ; if ((long)(iph + 1) > (long)skb->data_end)
> >   0: (61) r2 = *(u32 *)(r1 +80)         ; R1=ctx(off=0,imm=0) R2_w=pkt_end(off=0,imm=0)
> >   ; struct iphdr *iph = (void *)(long)skb->data + sizeof(struct ethhdr);
> >   1: (61) r1 = *(u32 *)(r1 +76)         ; R1_w=pkt(off=0,r=0,imm=0)
> >   ; if ((long)(iph + 1) > (long)skb->data_end)
> >   2: (07) r1 += 34                      ; R1_w=pkt(off=34,r=0,imm=0)
> >   3: (b4) w0 = 1                        ; R0_w=1
> >   4: (2d) if r1 > r2 goto pc+1
> >   R2 pointer comparison prohibited
> >   processed 5 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
> >   test_tc_bpf_non_root:FAIL:test_tc_bpf__open_and_load unexpected error: -13
> >   #233/2   tc_bpf_non_root:FAIL
> >
> > - With prev commit
> >
> >   $ tools/testing/selftests/bpf/test_progs --name=tc_bpf
> >   #232/1   tc_bpf/tc_bpf_root:OK
> >   #232/2   tc_bpf/tc_bpf_non_root:OK
> >   #232     tc_bpf:OK
> >   Summary: 1/2 PASSED, 0 SKIPPED, 0 FAILED
> >
> > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > ---
> >  tools/testing/selftests/bpf/prog_tests/tc_bpf.c | 36 ++++++++++++++++++++++++-
> >  tools/testing/selftests/bpf/progs/test_tc_bpf.c | 14 ++++++++++
> >  2 files changed, 49 insertions(+), 1 deletion(-)
> >
> > diff --git a/tools/testing/selftests/bpf/prog_tests/tc_bpf.c b/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
> > index e873766..48b5553 100644
> > --- a/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
> > +++ b/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
> > @@ -3,6 +3,7 @@
> >  #include <test_progs.h>
> >  #include <linux/pkt_cls.h>
> >
> > +#include "cap_helpers.h"
> >  #include "test_tc_bpf.skel.h"
> >
> >  #define LO_IFINDEX 1
> > @@ -327,7 +328,7 @@ static int test_tc_bpf_api(struct bpf_tc_hook *hook, int fd)
> >         return 0;
> >  }
> >
> > -void test_tc_bpf(void)
> > +void tc_bpf_root(void)
> >  {
> >         DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .ifindex = LO_IFINDEX,
> >                             .attach_point = BPF_TC_INGRESS);
> > @@ -393,3 +394,36 @@ void test_tc_bpf(void)
> >         }
> >         test_tc_bpf__destroy(skel);
> >  }
> > +
> > +void tc_bpf_non_root(void)
> > +{
> > +       struct test_tc_bpf *skel = NULL;
> > +       __u64 caps = 0;
> > +       int ret;
> > +
> > +       /* In case CAP_BPF and CAP_PERFMON is not set */
> > +       ret = cap_enable_effective(1ULL << CAP_BPF | 1ULL << CAP_NET_ADMIN, &caps);
> > +       if (!ASSERT_OK(ret, "set_cap_bpf_cap_net_admin"))
> > +               return;
> > +       ret = cap_disable_effective(1ULL << CAP_SYS_ADMIN | 1ULL << CAP_PERFMON, NULL);
> > +       if (!ASSERT_OK(ret, "disable_cap_sys_admin"))
> > +               goto restore_cap;
> > +
> > +       skel = test_tc_bpf__open_and_load();
> > +       if (!ASSERT_OK_PTR(skel, "test_tc_bpf__open_and_load"))
> > +               goto restore_cap;
> > +
> > +       test_tc_bpf__destroy(skel);
> > +
> > +restore_cap:
> > +       if (caps)
> > +               cap_enable_effective(caps, NULL);
> > +}
> > +
> > +void test_tc_bpf(void)
> > +{
> > +       if (test__start_subtest("tc_bpf_root"))
> > +               tc_bpf_root();
> > +       if (test__start_subtest("tc_bpf_non_root"))
> > +               tc_bpf_non_root();
> > +}
> > diff --git a/tools/testing/selftests/bpf/progs/test_tc_bpf.c b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > index d28ca8d..3e0f218 100644
> > --- a/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > +++ b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > @@ -1,5 +1,8 @@
> >  // SPDX-License-Identifier: GPL-2.0
> >
> > +#include <linux/pkt_cls.h>
> > +#include <linux/ip.h>
> > +#include <linux/if_ether.h>
>
> Due to above it fails to compile:
>
> In file included from progs/test_tc_bpf.c:4:
> In file included from /usr/include/linux/ip.h:21:
> In file included from /usr/include/asm/byteorder.h:5:
> In file included from /usr/include/linux/byteorder/little_endian.h:13:
> /usr/include/linux/swab.h:136:8: error: unknown type name '__always_inline'
>   136 | static __always_inline unsigned long __swab(const unsigned long y)
>       |        ^

I can't find the above error log in the BPF CI log.
The BPF CI log just shows that it fails the test_map on s390 without
logs. Not sure why.

__always_inline is defined in bpf_helpers.h, so I think below
additional change could fix it.

--- a/tools/testing/selftests/bpf/progs/test_tc_bpf.c
+++ b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
@@ -1,10 +1,10 @@
 // SPDX-License-Identifier: GPL-2.0

+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
 #include <linux/pkt_cls.h>
 #include <linux/ip.h>
 #include <linux/if_ether.h>
-#include <linux/bpf.h>
-#include <bpf/bpf_helpers.h>
Alexei Starovoitov Aug. 22, 2023, 3:28 a.m. UTC | #3
On Mon, Aug 21, 2023 at 7:43 PM Yafang Shao <laoar.shao@gmail.com> wrote:
>
> On Tue, Aug 22, 2023 at 6:45 AM Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> >
> > On Fri, Aug 18, 2023 at 1:39 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > >
> > > - Without prev commit
> > >
> > >   $ tools/testing/selftests/bpf/test_progs --name=tc_bpf
> > >   #232/1   tc_bpf/tc_bpf_root:OK
> > >   test_tc_bpf_non_root:PASS:set_cap_bpf_cap_net_admin 0 nsec
> > >   test_tc_bpf_non_root:PASS:disable_cap_sys_admin 0 nsec
> > >   0: R1=ctx(off=0,imm=0) R10=fp0
> > >   ; if ((long)(iph + 1) > (long)skb->data_end)
> > >   0: (61) r2 = *(u32 *)(r1 +80)         ; R1=ctx(off=0,imm=0) R2_w=pkt_end(off=0,imm=0)
> > >   ; struct iphdr *iph = (void *)(long)skb->data + sizeof(struct ethhdr);
> > >   1: (61) r1 = *(u32 *)(r1 +76)         ; R1_w=pkt(off=0,r=0,imm=0)
> > >   ; if ((long)(iph + 1) > (long)skb->data_end)
> > >   2: (07) r1 += 34                      ; R1_w=pkt(off=34,r=0,imm=0)
> > >   3: (b4) w0 = 1                        ; R0_w=1
> > >   4: (2d) if r1 > r2 goto pc+1
> > >   R2 pointer comparison prohibited
> > >   processed 5 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
> > >   test_tc_bpf_non_root:FAIL:test_tc_bpf__open_and_load unexpected error: -13
> > >   #233/2   tc_bpf_non_root:FAIL
> > >
> > > - With prev commit
> > >
> > >   $ tools/testing/selftests/bpf/test_progs --name=tc_bpf
> > >   #232/1   tc_bpf/tc_bpf_root:OK
> > >   #232/2   tc_bpf/tc_bpf_non_root:OK
> > >   #232     tc_bpf:OK
> > >   Summary: 1/2 PASSED, 0 SKIPPED, 0 FAILED
> > >
> > > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > > ---
> > >  tools/testing/selftests/bpf/prog_tests/tc_bpf.c | 36 ++++++++++++++++++++++++-
> > >  tools/testing/selftests/bpf/progs/test_tc_bpf.c | 14 ++++++++++
> > >  2 files changed, 49 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/tools/testing/selftests/bpf/prog_tests/tc_bpf.c b/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
> > > index e873766..48b5553 100644
> > > --- a/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
> > > +++ b/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
> > > @@ -3,6 +3,7 @@
> > >  #include <test_progs.h>
> > >  #include <linux/pkt_cls.h>
> > >
> > > +#include "cap_helpers.h"
> > >  #include "test_tc_bpf.skel.h"
> > >
> > >  #define LO_IFINDEX 1
> > > @@ -327,7 +328,7 @@ static int test_tc_bpf_api(struct bpf_tc_hook *hook, int fd)
> > >         return 0;
> > >  }
> > >
> > > -void test_tc_bpf(void)
> > > +void tc_bpf_root(void)
> > >  {
> > >         DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .ifindex = LO_IFINDEX,
> > >                             .attach_point = BPF_TC_INGRESS);
> > > @@ -393,3 +394,36 @@ void test_tc_bpf(void)
> > >         }
> > >         test_tc_bpf__destroy(skel);
> > >  }
> > > +
> > > +void tc_bpf_non_root(void)
> > > +{
> > > +       struct test_tc_bpf *skel = NULL;
> > > +       __u64 caps = 0;
> > > +       int ret;
> > > +
> > > +       /* In case CAP_BPF and CAP_PERFMON is not set */
> > > +       ret = cap_enable_effective(1ULL << CAP_BPF | 1ULL << CAP_NET_ADMIN, &caps);
> > > +       if (!ASSERT_OK(ret, "set_cap_bpf_cap_net_admin"))
> > > +               return;
> > > +       ret = cap_disable_effective(1ULL << CAP_SYS_ADMIN | 1ULL << CAP_PERFMON, NULL);
> > > +       if (!ASSERT_OK(ret, "disable_cap_sys_admin"))
> > > +               goto restore_cap;
> > > +
> > > +       skel = test_tc_bpf__open_and_load();
> > > +       if (!ASSERT_OK_PTR(skel, "test_tc_bpf__open_and_load"))
> > > +               goto restore_cap;
> > > +
> > > +       test_tc_bpf__destroy(skel);
> > > +
> > > +restore_cap:
> > > +       if (caps)
> > > +               cap_enable_effective(caps, NULL);
> > > +}
> > > +
> > > +void test_tc_bpf(void)
> > > +{
> > > +       if (test__start_subtest("tc_bpf_root"))
> > > +               tc_bpf_root();
> > > +       if (test__start_subtest("tc_bpf_non_root"))
> > > +               tc_bpf_non_root();
> > > +}
> > > diff --git a/tools/testing/selftests/bpf/progs/test_tc_bpf.c b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > > index d28ca8d..3e0f218 100644
> > > --- a/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > > +++ b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > > @@ -1,5 +1,8 @@
> > >  // SPDX-License-Identifier: GPL-2.0
> > >
> > > +#include <linux/pkt_cls.h>
> > > +#include <linux/ip.h>
> > > +#include <linux/if_ether.h>
> >
> > Due to above it fails to compile:
> >
> > In file included from progs/test_tc_bpf.c:4:
> > In file included from /usr/include/linux/ip.h:21:
> > In file included from /usr/include/asm/byteorder.h:5:
> > In file included from /usr/include/linux/byteorder/little_endian.h:13:
> > /usr/include/linux/swab.h:136:8: error: unknown type name '__always_inline'
> >   136 | static __always_inline unsigned long __swab(const unsigned long y)
> >       |        ^
>
> I can't find the above error log in the BPF CI log.
> The BPF CI log just shows that it fails the test_map on s390 without
> logs. Not sure why.

It's not in CI. I caught it by manual build.

> __always_inline is defined in bpf_helpers.h, so I think below
> additional change could fix it.
>
> --- a/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> +++ b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> @@ -1,10 +1,10 @@
>  // SPDX-License-Identifier: GPL-2.0
>
> +#include <linux/bpf.h>
> +#include <bpf/bpf_helpers.h>
>  #include <linux/pkt_cls.h>
>  #include <linux/ip.h>
>  #include <linux/if_ether.h>
> -#include <linux/bpf.h>
> -#include <bpf/bpf_helpers.h>

Maybe, but I'd rather remove the includes and replace
TC_ACT_STOLEN/ACT_OK with zeros, since the return values are
irrelevant.
Yafang Shao Aug. 22, 2023, 3:44 a.m. UTC | #4
On Tue, Aug 22, 2023 at 11:28 AM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Mon, Aug 21, 2023 at 7:43 PM Yafang Shao <laoar.shao@gmail.com> wrote:
> >
> > On Tue, Aug 22, 2023 at 6:45 AM Alexei Starovoitov
> > <alexei.starovoitov@gmail.com> wrote:
> > >
> > > On Fri, Aug 18, 2023 at 1:39 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> > > >
> > > > - Without prev commit
> > > >
> > > >   $ tools/testing/selftests/bpf/test_progs --name=tc_bpf
> > > >   #232/1   tc_bpf/tc_bpf_root:OK
> > > >   test_tc_bpf_non_root:PASS:set_cap_bpf_cap_net_admin 0 nsec
> > > >   test_tc_bpf_non_root:PASS:disable_cap_sys_admin 0 nsec
> > > >   0: R1=ctx(off=0,imm=0) R10=fp0
> > > >   ; if ((long)(iph + 1) > (long)skb->data_end)
> > > >   0: (61) r2 = *(u32 *)(r1 +80)         ; R1=ctx(off=0,imm=0) R2_w=pkt_end(off=0,imm=0)
> > > >   ; struct iphdr *iph = (void *)(long)skb->data + sizeof(struct ethhdr);
> > > >   1: (61) r1 = *(u32 *)(r1 +76)         ; R1_w=pkt(off=0,r=0,imm=0)
> > > >   ; if ((long)(iph + 1) > (long)skb->data_end)
> > > >   2: (07) r1 += 34                      ; R1_w=pkt(off=34,r=0,imm=0)
> > > >   3: (b4) w0 = 1                        ; R0_w=1
> > > >   4: (2d) if r1 > r2 goto pc+1
> > > >   R2 pointer comparison prohibited
> > > >   processed 5 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
> > > >   test_tc_bpf_non_root:FAIL:test_tc_bpf__open_and_load unexpected error: -13
> > > >   #233/2   tc_bpf_non_root:FAIL
> > > >
> > > > - With prev commit
> > > >
> > > >   $ tools/testing/selftests/bpf/test_progs --name=tc_bpf
> > > >   #232/1   tc_bpf/tc_bpf_root:OK
> > > >   #232/2   tc_bpf/tc_bpf_non_root:OK
> > > >   #232     tc_bpf:OK
> > > >   Summary: 1/2 PASSED, 0 SKIPPED, 0 FAILED
> > > >
> > > > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > > > ---
> > > >  tools/testing/selftests/bpf/prog_tests/tc_bpf.c | 36 ++++++++++++++++++++++++-
> > > >  tools/testing/selftests/bpf/progs/test_tc_bpf.c | 14 ++++++++++
> > > >  2 files changed, 49 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/tools/testing/selftests/bpf/prog_tests/tc_bpf.c b/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
> > > > index e873766..48b5553 100644
> > > > --- a/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
> > > > +++ b/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
> > > > @@ -3,6 +3,7 @@
> > > >  #include <test_progs.h>
> > > >  #include <linux/pkt_cls.h>
> > > >
> > > > +#include "cap_helpers.h"
> > > >  #include "test_tc_bpf.skel.h"
> > > >
> > > >  #define LO_IFINDEX 1
> > > > @@ -327,7 +328,7 @@ static int test_tc_bpf_api(struct bpf_tc_hook *hook, int fd)
> > > >         return 0;
> > > >  }
> > > >
> > > > -void test_tc_bpf(void)
> > > > +void tc_bpf_root(void)
> > > >  {
> > > >         DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .ifindex = LO_IFINDEX,
> > > >                             .attach_point = BPF_TC_INGRESS);
> > > > @@ -393,3 +394,36 @@ void test_tc_bpf(void)
> > > >         }
> > > >         test_tc_bpf__destroy(skel);
> > > >  }
> > > > +
> > > > +void tc_bpf_non_root(void)
> > > > +{
> > > > +       struct test_tc_bpf *skel = NULL;
> > > > +       __u64 caps = 0;
> > > > +       int ret;
> > > > +
> > > > +       /* In case CAP_BPF and CAP_PERFMON is not set */
> > > > +       ret = cap_enable_effective(1ULL << CAP_BPF | 1ULL << CAP_NET_ADMIN, &caps);
> > > > +       if (!ASSERT_OK(ret, "set_cap_bpf_cap_net_admin"))
> > > > +               return;
> > > > +       ret = cap_disable_effective(1ULL << CAP_SYS_ADMIN | 1ULL << CAP_PERFMON, NULL);
> > > > +       if (!ASSERT_OK(ret, "disable_cap_sys_admin"))
> > > > +               goto restore_cap;
> > > > +
> > > > +       skel = test_tc_bpf__open_and_load();
> > > > +       if (!ASSERT_OK_PTR(skel, "test_tc_bpf__open_and_load"))
> > > > +               goto restore_cap;
> > > > +
> > > > +       test_tc_bpf__destroy(skel);
> > > > +
> > > > +restore_cap:
> > > > +       if (caps)
> > > > +               cap_enable_effective(caps, NULL);
> > > > +}
> > > > +
> > > > +void test_tc_bpf(void)
> > > > +{
> > > > +       if (test__start_subtest("tc_bpf_root"))
> > > > +               tc_bpf_root();
> > > > +       if (test__start_subtest("tc_bpf_non_root"))
> > > > +               tc_bpf_non_root();
> > > > +}
> > > > diff --git a/tools/testing/selftests/bpf/progs/test_tc_bpf.c b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > > > index d28ca8d..3e0f218 100644
> > > > --- a/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > > > +++ b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > > > @@ -1,5 +1,8 @@
> > > >  // SPDX-License-Identifier: GPL-2.0
> > > >
> > > > +#include <linux/pkt_cls.h>
> > > > +#include <linux/ip.h>
> > > > +#include <linux/if_ether.h>
> > >
> > > Due to above it fails to compile:
> > >
> > > In file included from progs/test_tc_bpf.c:4:
> > > In file included from /usr/include/linux/ip.h:21:
> > > In file included from /usr/include/asm/byteorder.h:5:
> > > In file included from /usr/include/linux/byteorder/little_endian.h:13:
> > > /usr/include/linux/swab.h:136:8: error: unknown type name '__always_inline'
> > >   136 | static __always_inline unsigned long __swab(const unsigned long y)
> > >       |        ^
> >
> > I can't find the above error log in the BPF CI log.
> > The BPF CI log just shows that it fails the test_map on s390 without
> > logs. Not sure why.
>
> It's not in CI. I caught it by manual build.
>
> > __always_inline is defined in bpf_helpers.h, so I think below
> > additional change could fix it.
> >
> > --- a/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > +++ b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > @@ -1,10 +1,10 @@
> >  // SPDX-License-Identifier: GPL-2.0
> >
> > +#include <linux/bpf.h>
> > +#include <bpf/bpf_helpers.h>
> >  #include <linux/pkt_cls.h>
> >  #include <linux/ip.h>
> >  #include <linux/if_ether.h>
> > -#include <linux/bpf.h>
> > -#include <bpf/bpf_helpers.h>
>
> Maybe, but I'd rather remove the includes and replace
> TC_ACT_STOLEN/ACT_OK with zeros, since the return values are
> irrelevant.

Good point. That could remove the "linux/pkt_cls.h".
Eduard Zingerman Aug. 23, 2023, 9:44 a.m. UTC | #5
On Mon, 2023-08-21 at 15:45 -0700, Alexei Starovoitov wrote:
[...]
> > diff --git a/tools/testing/selftests/bpf/progs/test_tc_bpf.c b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > index d28ca8d..3e0f218 100644
> > --- a/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > +++ b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > @@ -1,5 +1,8 @@
> >  // SPDX-License-Identifier: GPL-2.0
> > 
> > +#include <linux/pkt_cls.h>
> > +#include <linux/ip.h>
> > +#include <linux/if_ether.h>
> 
> Due to above it fails to compile:
> 
> In file included from progs/test_tc_bpf.c:4:
> In file included from /usr/include/linux/ip.h:21:
> In file included from /usr/include/asm/byteorder.h:5:
> In file included from /usr/include/linux/byteorder/little_endian.h:13:
> /usr/include/linux/swab.h:136:8: error: unknown type name '__always_inline'
>   136 | static __always_inline unsigned long __swab(const unsigned long y)
>       |        ^
> 

This is strange, I can compile it no problem. On my system:
/usr/include/linux/swab.h includes /usr/include/linux/stddef.h
which defines __always_inline.

What distro are you using?
I want to try it in chroot to see if we have any issues with test makefiles.
Alexei Starovoitov Aug. 23, 2023, 3:51 p.m. UTC | #6
On Wed, Aug 23, 2023 at 2:45 AM Eduard Zingerman <eddyz87@gmail.com> wrote:
>
> On Mon, 2023-08-21 at 15:45 -0700, Alexei Starovoitov wrote:
> [...]
> > > diff --git a/tools/testing/selftests/bpf/progs/test_tc_bpf.c b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > > index d28ca8d..3e0f218 100644
> > > --- a/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > > +++ b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
> > > @@ -1,5 +1,8 @@
> > >  // SPDX-License-Identifier: GPL-2.0
> > >
> > > +#include <linux/pkt_cls.h>
> > > +#include <linux/ip.h>
> > > +#include <linux/if_ether.h>
> >
> > Due to above it fails to compile:
> >
> > In file included from progs/test_tc_bpf.c:4:
> > In file included from /usr/include/linux/ip.h:21:
> > In file included from /usr/include/asm/byteorder.h:5:
> > In file included from /usr/include/linux/byteorder/little_endian.h:13:
> > /usr/include/linux/swab.h:136:8: error: unknown type name '__always_inline'
> >   136 | static __always_inline unsigned long __swab(const unsigned long y)
> >       |        ^
> >
>
> This is strange, I can compile it no problem. On my system:
> /usr/include/linux/swab.h includes /usr/include/linux/stddef.h
> which defines __always_inline.
>
> What distro are you using?

That was centos8.
dnf provides /usr/include/linux/swab.h
kernel-headers-6.4.3.x86_64 : Header files for the Linux kernel for use by glibc
Repo        : kernel
Matched from:
Filename    : /usr/include/linux/swab.h
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/prog_tests/tc_bpf.c b/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
index e873766..48b5553 100644
--- a/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
+++ b/tools/testing/selftests/bpf/prog_tests/tc_bpf.c
@@ -3,6 +3,7 @@ 
 #include <test_progs.h>
 #include <linux/pkt_cls.h>
 
+#include "cap_helpers.h"
 #include "test_tc_bpf.skel.h"
 
 #define LO_IFINDEX 1
@@ -327,7 +328,7 @@  static int test_tc_bpf_api(struct bpf_tc_hook *hook, int fd)
 	return 0;
 }
 
-void test_tc_bpf(void)
+void tc_bpf_root(void)
 {
 	DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .ifindex = LO_IFINDEX,
 			    .attach_point = BPF_TC_INGRESS);
@@ -393,3 +394,36 @@  void test_tc_bpf(void)
 	}
 	test_tc_bpf__destroy(skel);
 }
+
+void tc_bpf_non_root(void)
+{
+	struct test_tc_bpf *skel = NULL;
+	__u64 caps = 0;
+	int ret;
+
+	/* In case CAP_BPF and CAP_PERFMON is not set */
+	ret = cap_enable_effective(1ULL << CAP_BPF | 1ULL << CAP_NET_ADMIN, &caps);
+	if (!ASSERT_OK(ret, "set_cap_bpf_cap_net_admin"))
+		return;
+	ret = cap_disable_effective(1ULL << CAP_SYS_ADMIN | 1ULL << CAP_PERFMON, NULL);
+	if (!ASSERT_OK(ret, "disable_cap_sys_admin"))
+		goto restore_cap;
+
+	skel = test_tc_bpf__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "test_tc_bpf__open_and_load"))
+		goto restore_cap;
+
+	test_tc_bpf__destroy(skel);
+
+restore_cap:
+	if (caps)
+		cap_enable_effective(caps, NULL);
+}
+
+void test_tc_bpf(void)
+{
+	if (test__start_subtest("tc_bpf_root"))
+		tc_bpf_root();
+	if (test__start_subtest("tc_bpf_non_root"))
+		tc_bpf_non_root();
+}
diff --git a/tools/testing/selftests/bpf/progs/test_tc_bpf.c b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
index d28ca8d..3e0f218 100644
--- a/tools/testing/selftests/bpf/progs/test_tc_bpf.c
+++ b/tools/testing/selftests/bpf/progs/test_tc_bpf.c
@@ -1,5 +1,8 @@ 
 // SPDX-License-Identifier: GPL-2.0
 
+#include <linux/pkt_cls.h>
+#include <linux/ip.h>
+#include <linux/if_ether.h>
 #include <linux/bpf.h>
 #include <bpf/bpf_helpers.h>
 
@@ -10,3 +13,14 @@  int cls(struct __sk_buff *skb)
 {
 	return 0;
 }
+
+/* Prog to verify tc-bpf without cap_sys_admin and cap_perfmon */
+SEC("tcx/ingress")
+int pkt_ptr(struct __sk_buff *skb)
+{
+	struct iphdr *iph = (void *)(long)skb->data + sizeof(struct ethhdr);
+
+	if ((long)(iph + 1) > (long)skb->data_end)
+		return TC_ACT_STOLEN;
+	return TC_ACT_OK;
+}