* [PATCH bpf-next 1/2] bpf: Fix context type resolving for extension programs @ 2020-09-09 15:11 Jiri Olsa 2020-09-09 15:11 ` [PATCH bpf-next 2/2] selftests/bpf: Adding test for arg dereference in extension trace Jiri Olsa ` (2 more replies) 0 siblings, 3 replies; 10+ messages in thread From: Jiri Olsa @ 2020-09-09 15:11 UTC (permalink / raw) To: Alexei Starovoitov, Daniel Borkmann Cc: Eelco Chaudron, netdev, bpf, Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko, John Fastabend, KP Singh, Jesper Dangaard Brouer, Toke Høiland-Jørgensen Eelco reported we can't properly access arguments if the tracing program is attached to extension program. Having following program: SEC("classifier/test_pkt_md_access") int test_pkt_md_access(struct __sk_buff *skb) with its extension: SEC("freplace/test_pkt_md_access") int test_pkt_md_access_new(struct __sk_buff *skb) and tracing that extension with: SEC("fentry/test_pkt_md_access_new") int BPF_PROG(fentry, struct sk_buff *skb) It's not possible to access skb argument in the fentry program, with following error from verifier: ; int BPF_PROG(fentry, struct sk_buff *skb) 0: (79) r1 = *(u64 *)(r1 +0) invalid bpf_context access off=0 size=8 The problem is that btf_ctx_access gets the context type for the traced program, which is in this case the extension. But when we trace extension program, we want to get the context type of the program that the extension is attached to, so we can access the argument properly in the trace program. Reported-by: Eelco Chaudron <echaudro@redhat.com> Signed-off-by: Jiri Olsa <jolsa@kernel.org> --- kernel/bpf/btf.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index f9ac6935ab3c..37ad01c32e5a 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -3859,6 +3859,14 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type, } info->reg_type = PTR_TO_BTF_ID; + + /* When we trace extension program, we want to get the context + * type of the program that the extension is attached to, so + * we can access the argument properly in the trace program. + */ + if (tgt_prog && tgt_prog->type == BPF_PROG_TYPE_EXT) + tgt_prog = tgt_prog->aux->linked_prog; + if (tgt_prog) { ret = btf_translate_to_vmlinux(log, btf, t, tgt_prog->type, arg); if (ret > 0) { -- 2.26.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH bpf-next 2/2] selftests/bpf: Adding test for arg dereference in extension trace 2020-09-09 15:11 [PATCH bpf-next 1/2] bpf: Fix context type resolving for extension programs Jiri Olsa @ 2020-09-09 15:11 ` Jiri Olsa 2020-09-10 22:34 ` Andrii Nakryiko 2020-09-09 15:54 ` [PATCH bpf-next 1/2] bpf: Fix context type resolving for extension programs Toke Høiland-Jørgensen 2020-09-10 18:00 ` Alexei Starovoitov 2 siblings, 1 reply; 10+ messages in thread From: Jiri Olsa @ 2020-09-09 15:11 UTC (permalink / raw) To: Alexei Starovoitov, Daniel Borkmann Cc: netdev, bpf, Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko, John Fastabend, KP Singh, Jesper Dangaard Brouer, Eelco Chaudron, Toke Høiland-Jørgensen Adding test that setup following program: SEC("classifier/test_pkt_md_access") int test_pkt_md_access(struct __sk_buff *skb) with its extension: SEC("freplace/test_pkt_md_access") int test_pkt_md_access_new(struct __sk_buff *skb) and tracing that extension with: SEC("fentry/test_pkt_md_access_new") int BPF_PROG(fentry, struct sk_buff *skb) The test verifies that the tracing program can dereference skb argument properly. Signed-off-by: Jiri Olsa <jolsa@kernel.org> --- .../selftests/bpf/prog_tests/trace_ext.c | 93 +++++++++++++++++++ .../selftests/bpf/progs/test_trace_ext.c | 18 ++++ .../bpf/progs/test_trace_ext_tracing.c | 25 +++++ 3 files changed, 136 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/trace_ext.c create mode 100644 tools/testing/selftests/bpf/progs/test_trace_ext.c create mode 100644 tools/testing/selftests/bpf/progs/test_trace_ext_tracing.c diff --git a/tools/testing/selftests/bpf/prog_tests/trace_ext.c b/tools/testing/selftests/bpf/prog_tests/trace_ext.c new file mode 100644 index 000000000000..1089dafb4653 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/trace_ext.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0 + +#define _GNU_SOURCE +#include <test_progs.h> +#include <network_helpers.h> +#include <sys/stat.h> +#include <linux/sched.h> +#include <sys/syscall.h> + +#include "test_trace_ext.skel.h" +#include "test_trace_ext_tracing.skel.h" + +static __u32 duration; + +void test_trace_ext(void) +{ + struct test_trace_ext_tracing *skel_trace = NULL; + struct test_trace_ext_tracing__bss *bss_trace; + const char *file = "./test_pkt_md_access.o"; + struct test_trace_ext *skel_ext = NULL; + struct test_trace_ext__bss *bss_ext; + int err, prog_fd, ext_fd; + struct bpf_object *obj; + char buf[100]; + __u32 retval; + __u64 len; + + err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd); + if (CHECK_FAIL(err)) + return; + + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, + .attach_prog_fd = prog_fd, + ); + + skel_ext = test_trace_ext__open_opts(&opts); + if (CHECK(!skel_ext, "setup", "freplace/test_pkt_md_access open failed\n")) + goto cleanup; + + err = test_trace_ext__load(skel_ext); + if (CHECK(err, "setup", "freplace/test_pkt_md_access load failed\n")) { + libbpf_strerror(err, buf, sizeof(buf)); + fprintf(stderr, "%s\n", buf); + goto cleanup; + } + + err = test_trace_ext__attach(skel_ext); + if (CHECK(err, "setup", "freplace/test_pkt_md_access attach failed: %d\n", err)) + goto cleanup; + + ext_fd = bpf_program__fd(skel_ext->progs.test_pkt_md_access_new); + + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts_trace, + .attach_prog_fd = ext_fd, + ); + + skel_trace = test_trace_ext_tracing__open_opts(&opts_trace); + if (CHECK(!skel_trace, "setup", "tracing/test_pkt_md_access_new open failed\n")) + goto cleanup; + + err = test_trace_ext_tracing__load(skel_trace); + if (CHECK(err, "setup", "tracing/test_pkt_md_access_new load failed\n")) { + libbpf_strerror(err, buf, sizeof(buf)); + fprintf(stderr, "%s\n", buf); + goto cleanup; + } + + err = test_trace_ext_tracing__attach(skel_trace); + if (CHECK(err, "setup", "tracing/test_pkt_md_access_new attach failed: %d\n", err)) + goto cleanup; + + err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), + NULL, NULL, &retval, &duration); + CHECK(err || retval, "", + "err %d errno %d retval %d duration %d\n", + err, errno, retval, duration); + + bss_ext = skel_ext->bss; + bss_trace = skel_trace->bss; + + len = bss_ext->ext_called; + + CHECK(bss_ext->ext_called == 0, + "check", "failed to trigger freplace/test_pkt_md_access\n"); + CHECK(bss_trace->fentry_called != len, + "check", "failed to trigger fentry/test_pkt_md_access_new\n"); + CHECK(bss_trace->fexit_called != len, + "check", "failed to trigger fexit/test_pkt_md_access_new\n"); + +cleanup: + test_trace_ext__destroy(skel_ext); + bpf_object__close(obj); +} diff --git a/tools/testing/selftests/bpf/progs/test_trace_ext.c b/tools/testing/selftests/bpf/progs/test_trace_ext.c new file mode 100644 index 000000000000..a6318f6b52ee --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_trace_ext.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Facebook +#include <linux/bpf.h> +#include <stdbool.h> +#include <bpf/bpf_helpers.h> +#include <bpf/bpf_endian.h> +#include <bpf/bpf_tracing.h> + +volatile __u64 ext_called = 0; + +SEC("freplace/test_pkt_md_access") +int test_pkt_md_access_new(struct __sk_buff *skb) +{ + ext_called = skb->len; + return 0; +} + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/test_trace_ext_tracing.c b/tools/testing/selftests/bpf/progs/test_trace_ext_tracing.c new file mode 100644 index 000000000000..9e52a831446f --- /dev/null +++ b/tools/testing/selftests/bpf/progs/test_trace_ext_tracing.c @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "vmlinux.h" +#include <bpf/bpf_helpers.h> +#include <bpf/bpf_tracing.h> + +volatile __u64 fentry_called = 0; + +SEC("fentry/test_pkt_md_access_new") +int BPF_PROG(fentry, struct sk_buff *skb) +{ + fentry_called = skb->len; + return 0; +} + +volatile __u64 fexit_called = 0; + +SEC("fexit/test_pkt_md_access_new") +int BPF_PROG(fexit, struct sk_buff *skb) +{ + fexit_called = skb->len; + return 0; +} + +char _license[] SEC("license") = "GPL"; -- 2.26.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 2/2] selftests/bpf: Adding test for arg dereference in extension trace 2020-09-09 15:11 ` [PATCH bpf-next 2/2] selftests/bpf: Adding test for arg dereference in extension trace Jiri Olsa @ 2020-09-10 22:34 ` Andrii Nakryiko 2020-09-11 11:01 ` Toke Høiland-Jørgensen 2020-09-11 13:02 ` Jiri Olsa 0 siblings, 2 replies; 10+ messages in thread From: Andrii Nakryiko @ 2020-09-10 22:34 UTC (permalink / raw) To: Jiri Olsa Cc: Alexei Starovoitov, Daniel Borkmann, Networking, bpf, Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko, John Fastabend, KP Singh, Jesper Dangaard Brouer, Eelco Chaudron, Toke Høiland-Jørgensen On Wed, Sep 9, 2020 at 8:38 AM Jiri Olsa <jolsa@kernel.org> wrote: > > Adding test that setup following program: > > SEC("classifier/test_pkt_md_access") > int test_pkt_md_access(struct __sk_buff *skb) > > with its extension: > > SEC("freplace/test_pkt_md_access") > int test_pkt_md_access_new(struct __sk_buff *skb) > > and tracing that extension with: > > SEC("fentry/test_pkt_md_access_new") > int BPF_PROG(fentry, struct sk_buff *skb) > > The test verifies that the tracing program can > dereference skb argument properly. > > Signed-off-by: Jiri Olsa <jolsa@kernel.org> > --- > .../selftests/bpf/prog_tests/trace_ext.c | 93 +++++++++++++++++++ > .../selftests/bpf/progs/test_trace_ext.c | 18 ++++ > .../bpf/progs/test_trace_ext_tracing.c | 25 +++++ > 3 files changed, 136 insertions(+) > create mode 100644 tools/testing/selftests/bpf/prog_tests/trace_ext.c > create mode 100644 tools/testing/selftests/bpf/progs/test_trace_ext.c > create mode 100644 tools/testing/selftests/bpf/progs/test_trace_ext_tracing.c > > diff --git a/tools/testing/selftests/bpf/prog_tests/trace_ext.c b/tools/testing/selftests/bpf/prog_tests/trace_ext.c > new file mode 100644 > index 000000000000..1089dafb4653 > --- /dev/null > +++ b/tools/testing/selftests/bpf/prog_tests/trace_ext.c > @@ -0,0 +1,93 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#define _GNU_SOURCE > +#include <test_progs.h> > +#include <network_helpers.h> > +#include <sys/stat.h> > +#include <linux/sched.h> > +#include <sys/syscall.h> > + > +#include "test_trace_ext.skel.h" > +#include "test_trace_ext_tracing.skel.h" > + > +static __u32 duration; > + > +void test_trace_ext(void) > +{ > + struct test_trace_ext_tracing *skel_trace = NULL; > + struct test_trace_ext_tracing__bss *bss_trace; > + const char *file = "./test_pkt_md_access.o"; > + struct test_trace_ext *skel_ext = NULL; > + struct test_trace_ext__bss *bss_ext; > + int err, prog_fd, ext_fd; > + struct bpf_object *obj; > + char buf[100]; > + __u32 retval; > + __u64 len; > + > + err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd); > + if (CHECK_FAIL(err)) > + return; We should avoid using bpf_prog_load() for new code. Can you please just skeleton instead? Or at least bpf_object__open_file()? > + > + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, > + .attach_prog_fd = prog_fd, > + ); DECLARE_LIBBPF_OPTS does declare a variable, so should be together with all the other variables above, otherwise some overly strict C89 mode compiler will start complaining. You can assign `opts.attach_prog_fd = prog_fd;` outside of declaration. But I also don't think you need this one. Having .attach_prog_fd in open_opts is not great, because it's a per-program setting specified at bpf_object level. Would bpf_program__set_attach_target() work here? > + > + skel_ext = test_trace_ext__open_opts(&opts); > + if (CHECK(!skel_ext, "setup", "freplace/test_pkt_md_access open failed\n")) > + goto cleanup; > + > + err = test_trace_ext__load(skel_ext); > + if (CHECK(err, "setup", "freplace/test_pkt_md_access load failed\n")) { > + libbpf_strerror(err, buf, sizeof(buf)); > + fprintf(stderr, "%s\n", buf); > + goto cleanup; > + } > + > + err = test_trace_ext__attach(skel_ext); > + if (CHECK(err, "setup", "freplace/test_pkt_md_access attach failed: %d\n", err)) > + goto cleanup; > + > + ext_fd = bpf_program__fd(skel_ext->progs.test_pkt_md_access_new); > + > + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts_trace, > + .attach_prog_fd = ext_fd, > + ); > + same > + skel_trace = test_trace_ext_tracing__open_opts(&opts_trace); > + if (CHECK(!skel_trace, "setup", "tracing/test_pkt_md_access_new open failed\n")) > + goto cleanup; > + > + err = test_trace_ext_tracing__load(skel_trace); > + if (CHECK(err, "setup", "tracing/test_pkt_md_access_new load failed\n")) { > + libbpf_strerror(err, buf, sizeof(buf)); > + fprintf(stderr, "%s\n", buf); > + goto cleanup; > + } > + > + err = test_trace_ext_tracing__attach(skel_trace); > + if (CHECK(err, "setup", "tracing/test_pkt_md_access_new attach failed: %d\n", err)) > + goto cleanup; > + > + err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), > + NULL, NULL, &retval, &duration); > + CHECK(err || retval, "", > + "err %d errno %d retval %d duration %d\n", > + err, errno, retval, duration); > + > + bss_ext = skel_ext->bss; > + bss_trace = skel_trace->bss; > + > + len = bss_ext->ext_called; > + > + CHECK(bss_ext->ext_called == 0, > + "check", "failed to trigger freplace/test_pkt_md_access\n"); > + CHECK(bss_trace->fentry_called != len, > + "check", "failed to trigger fentry/test_pkt_md_access_new\n"); > + CHECK(bss_trace->fexit_called != len, > + "check", "failed to trigger fexit/test_pkt_md_access_new\n"); > + > +cleanup: > + test_trace_ext__destroy(skel_ext); > + bpf_object__close(obj); > +} > diff --git a/tools/testing/selftests/bpf/progs/test_trace_ext.c b/tools/testing/selftests/bpf/progs/test_trace_ext.c > new file mode 100644 > index 000000000000..a6318f6b52ee > --- /dev/null > +++ b/tools/testing/selftests/bpf/progs/test_trace_ext.c > @@ -0,0 +1,18 @@ > +// SPDX-License-Identifier: GPL-2.0 > +// Copyright (c) 2019 Facebook > +#include <linux/bpf.h> > +#include <stdbool.h> > +#include <bpf/bpf_helpers.h> > +#include <bpf/bpf_endian.h> > +#include <bpf/bpf_tracing.h> > + > +volatile __u64 ext_called = 0; nit: no need for volatile, global variables are not going anywhere; same below in two places > + > +SEC("freplace/test_pkt_md_access") > +int test_pkt_md_access_new(struct __sk_buff *skb) > +{ > + ext_called = skb->len; > + return 0; > +} > + > +char _license[] SEC("license") = "GPL"; > diff --git a/tools/testing/selftests/bpf/progs/test_trace_ext_tracing.c b/tools/testing/selftests/bpf/progs/test_trace_ext_tracing.c > new file mode 100644 > index 000000000000..9e52a831446f > --- /dev/null > +++ b/tools/testing/selftests/bpf/progs/test_trace_ext_tracing.c > @@ -0,0 +1,25 @@ > +// SPDX-License-Identifier: GPL-2.0 > + > +#include "vmlinux.h" > +#include <bpf/bpf_helpers.h> > +#include <bpf/bpf_tracing.h> > + > +volatile __u64 fentry_called = 0; > + > +SEC("fentry/test_pkt_md_access_new") > +int BPF_PROG(fentry, struct sk_buff *skb) > +{ > + fentry_called = skb->len; > + return 0; > +} > + > +volatile __u64 fexit_called = 0; > + > +SEC("fexit/test_pkt_md_access_new") > +int BPF_PROG(fexit, struct sk_buff *skb) > +{ > + fexit_called = skb->len; > + return 0; > +} > + > +char _license[] SEC("license") = "GPL"; > -- > 2.26.2 > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 2/2] selftests/bpf: Adding test for arg dereference in extension trace 2020-09-10 22:34 ` Andrii Nakryiko @ 2020-09-11 11:01 ` Toke Høiland-Jørgensen 2020-09-11 13:02 ` Jiri Olsa 1 sibling, 0 replies; 10+ messages in thread From: Toke Høiland-Jørgensen @ 2020-09-11 11:01 UTC (permalink / raw) To: Andrii Nakryiko, Jiri Olsa Cc: Alexei Starovoitov, Daniel Borkmann, Networking, bpf, Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko, John Fastabend, KP Singh, Jesper Dangaard Brouer, Eelco Chaudron Andrii Nakryiko <andrii.nakryiko@gmail.com> writes: > On Wed, Sep 9, 2020 at 8:38 AM Jiri Olsa <jolsa@kernel.org> wrote: >> >> Adding test that setup following program: >> >> SEC("classifier/test_pkt_md_access") >> int test_pkt_md_access(struct __sk_buff *skb) >> >> with its extension: >> >> SEC("freplace/test_pkt_md_access") >> int test_pkt_md_access_new(struct __sk_buff *skb) >> >> and tracing that extension with: >> >> SEC("fentry/test_pkt_md_access_new") >> int BPF_PROG(fentry, struct sk_buff *skb) >> >> The test verifies that the tracing program can >> dereference skb argument properly. >> >> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Just FYI, I included this same patch in my freplace series. I didn't change anything in the version I just resent, but I'll work with Jiri and get an updated version of this into the next version based on your comments here... :) -Toke ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 2/2] selftests/bpf: Adding test for arg dereference in extension trace 2020-09-10 22:34 ` Andrii Nakryiko 2020-09-11 11:01 ` Toke Høiland-Jørgensen @ 2020-09-11 13:02 ` Jiri Olsa 1 sibling, 0 replies; 10+ messages in thread From: Jiri Olsa @ 2020-09-11 13:02 UTC (permalink / raw) To: Andrii Nakryiko Cc: Jiri Olsa, Alexei Starovoitov, Daniel Borkmann, Networking, bpf, Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko, John Fastabend, KP Singh, Jesper Dangaard Brouer, Eelco Chaudron, Toke Høiland-Jørgensen On Thu, Sep 10, 2020 at 03:34:26PM -0700, Andrii Nakryiko wrote: SNIP > > + > > +void test_trace_ext(void) > > +{ > > + struct test_trace_ext_tracing *skel_trace = NULL; > > + struct test_trace_ext_tracing__bss *bss_trace; > > + const char *file = "./test_pkt_md_access.o"; > > + struct test_trace_ext *skel_ext = NULL; > > + struct test_trace_ext__bss *bss_ext; > > + int err, prog_fd, ext_fd; > > + struct bpf_object *obj; > > + char buf[100]; > > + __u32 retval; > > + __u64 len; > > + > > + err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd); > > + if (CHECK_FAIL(err)) > > + return; > > We should avoid using bpf_prog_load() for new code. Can you please > just skeleton instead? Or at least bpf_object__open_file()? ok > > > + > > + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, > > + .attach_prog_fd = prog_fd, > > + ); > > DECLARE_LIBBPF_OPTS does declare a variable, so should be together > with all the other variables above, otherwise some overly strict C89 > mode compiler will start complaining. You can assign > `opts.attach_prog_fd = prog_fd;` outside of declaration. But I also > don't think you need this one. Having .attach_prog_fd in open_opts is > not great, because it's a per-program setting specified at bpf_object > level. Would bpf_program__set_attach_target() work here? right, I'll try it, it should be enough SNIP > > + > > +cleanup: > > + test_trace_ext__destroy(skel_ext); > > + bpf_object__close(obj); > > +} > > diff --git a/tools/testing/selftests/bpf/progs/test_trace_ext.c b/tools/testing/selftests/bpf/progs/test_trace_ext.c > > new file mode 100644 > > index 000000000000..a6318f6b52ee > > --- /dev/null > > +++ b/tools/testing/selftests/bpf/progs/test_trace_ext.c > > @@ -0,0 +1,18 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +// Copyright (c) 2019 Facebook > > +#include <linux/bpf.h> > > +#include <stdbool.h> > > +#include <bpf/bpf_helpers.h> > > +#include <bpf/bpf_endian.h> > > +#include <bpf/bpf_tracing.h> > > + > > +volatile __u64 ext_called = 0; > > nit: no need for volatile, global variables are not going anywhere; > same below in two places ok, thanks jirka ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: Fix context type resolving for extension programs 2020-09-09 15:11 [PATCH bpf-next 1/2] bpf: Fix context type resolving for extension programs Jiri Olsa 2020-09-09 15:11 ` [PATCH bpf-next 2/2] selftests/bpf: Adding test for arg dereference in extension trace Jiri Olsa @ 2020-09-09 15:54 ` Toke Høiland-Jørgensen 2020-09-09 18:58 ` Jiri Olsa 2020-09-10 18:00 ` Alexei Starovoitov 2 siblings, 1 reply; 10+ messages in thread From: Toke Høiland-Jørgensen @ 2020-09-09 15:54 UTC (permalink / raw) To: Jiri Olsa, Alexei Starovoitov, Daniel Borkmann Cc: Eelco Chaudron, netdev, bpf, Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko, John Fastabend, KP Singh, Jesper Dangaard Brouer Jiri Olsa <jolsa@kernel.org> writes: > Eelco reported we can't properly access arguments if the tracing > program is attached to extension program. > > Having following program: > > SEC("classifier/test_pkt_md_access") > int test_pkt_md_access(struct __sk_buff *skb) > > with its extension: > > SEC("freplace/test_pkt_md_access") > int test_pkt_md_access_new(struct __sk_buff *skb) > > and tracing that extension with: > > SEC("fentry/test_pkt_md_access_new") > int BPF_PROG(fentry, struct sk_buff *skb) > > It's not possible to access skb argument in the fentry program, > with following error from verifier: > > ; int BPF_PROG(fentry, struct sk_buff *skb) > 0: (79) r1 = *(u64 *)(r1 +0) > invalid bpf_context access off=0 size=8 > > The problem is that btf_ctx_access gets the context type for the > traced program, which is in this case the extension. > > But when we trace extension program, we want to get the context > type of the program that the extension is attached to, so we can > access the argument properly in the trace program. > > Reported-by: Eelco Chaudron <echaudro@redhat.com> > Signed-off-by: Jiri Olsa <jolsa@kernel.org> > --- > kernel/bpf/btf.c | 8 ++++++++ > 1 file changed, 8 insertions(+) > > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c > index f9ac6935ab3c..37ad01c32e5a 100644 > --- a/kernel/bpf/btf.c > +++ b/kernel/bpf/btf.c > @@ -3859,6 +3859,14 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type, > } > > info->reg_type = PTR_TO_BTF_ID; > + > + /* When we trace extension program, we want to get the context > + * type of the program that the extension is attached to, so > + * we can access the argument properly in the trace program. > + */ > + if (tgt_prog && tgt_prog->type == BPF_PROG_TYPE_EXT) > + tgt_prog = tgt_prog->aux->linked_prog; > + In the discussion about multi-attach for freplace we kinda concluded[0] that this linked_prog pointer was going away after attach. I have this basically working, but need to test a bit more before posting it (see [1] for current status). But with this I guess we'll need to either do something different? Maybe go chase down the target via the bpf_link or something? -Toke [0] https://lore.kernel.org/bpf/20200722002918.574pruibvlxfblyq@ast-mbp.dhcp.thefacebook.com/ [1] https://git.kernel.org/pub/scm/linux/kernel/git/toke/linux.git/log/?h=bpf-freplace-multi-attach-alt-03 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: Fix context type resolving for extension programs 2020-09-09 15:54 ` [PATCH bpf-next 1/2] bpf: Fix context type resolving for extension programs Toke Høiland-Jørgensen @ 2020-09-09 18:58 ` Jiri Olsa 2020-09-10 9:49 ` Toke Høiland-Jørgensen 0 siblings, 1 reply; 10+ messages in thread From: Jiri Olsa @ 2020-09-09 18:58 UTC (permalink / raw) To: Toke Høiland-Jørgensen Cc: Jiri Olsa, Alexei Starovoitov, Daniel Borkmann, Eelco Chaudron, netdev, bpf, Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko, John Fastabend, KP Singh, Jesper Dangaard Brouer On Wed, Sep 09, 2020 at 05:54:58PM +0200, Toke Høiland-Jørgensen wrote: > Jiri Olsa <jolsa@kernel.org> writes: > > > Eelco reported we can't properly access arguments if the tracing > > program is attached to extension program. > > > > Having following program: > > > > SEC("classifier/test_pkt_md_access") > > int test_pkt_md_access(struct __sk_buff *skb) > > > > with its extension: > > > > SEC("freplace/test_pkt_md_access") > > int test_pkt_md_access_new(struct __sk_buff *skb) > > > > and tracing that extension with: > > > > SEC("fentry/test_pkt_md_access_new") > > int BPF_PROG(fentry, struct sk_buff *skb) > > > > It's not possible to access skb argument in the fentry program, > > with following error from verifier: > > > > ; int BPF_PROG(fentry, struct sk_buff *skb) > > 0: (79) r1 = *(u64 *)(r1 +0) > > invalid bpf_context access off=0 size=8 > > > > The problem is that btf_ctx_access gets the context type for the > > traced program, which is in this case the extension. > > > > But when we trace extension program, we want to get the context > > type of the program that the extension is attached to, so we can > > access the argument properly in the trace program. > > > > Reported-by: Eelco Chaudron <echaudro@redhat.com> > > Signed-off-by: Jiri Olsa <jolsa@kernel.org> > > --- > > kernel/bpf/btf.c | 8 ++++++++ > > 1 file changed, 8 insertions(+) > > > > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c > > index f9ac6935ab3c..37ad01c32e5a 100644 > > --- a/kernel/bpf/btf.c > > +++ b/kernel/bpf/btf.c > > @@ -3859,6 +3859,14 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type, > > } > > > > info->reg_type = PTR_TO_BTF_ID; > > + > > + /* When we trace extension program, we want to get the context > > + * type of the program that the extension is attached to, so > > + * we can access the argument properly in the trace program. > > + */ > > + if (tgt_prog && tgt_prog->type == BPF_PROG_TYPE_EXT) > > + tgt_prog = tgt_prog->aux->linked_prog; > > + > > In the discussion about multi-attach for freplace we kinda concluded[0] > that this linked_prog pointer was going away after attach. I have this > basically working, but need to test a bit more before posting it (see > [1] for current status). ok, feel free to use the test case from patch 2 ;-) > > But with this I guess we'll need to either do something different? Maybe > go chase down the target via the bpf_link or something? I'll check, could you please CC me on your next post? thanks, jirka ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: Fix context type resolving for extension programs 2020-09-09 18:58 ` Jiri Olsa @ 2020-09-10 9:49 ` Toke Høiland-Jørgensen 0 siblings, 0 replies; 10+ messages in thread From: Toke Høiland-Jørgensen @ 2020-09-10 9:49 UTC (permalink / raw) To: Jiri Olsa Cc: Jiri Olsa, Alexei Starovoitov, Daniel Borkmann, Eelco Chaudron, netdev, bpf, Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko, John Fastabend, KP Singh, Jesper Dangaard Brouer Jiri Olsa <jolsa@redhat.com> writes: > On Wed, Sep 09, 2020 at 05:54:58PM +0200, Toke Høiland-Jørgensen wrote: >> Jiri Olsa <jolsa@kernel.org> writes: >> >> > Eelco reported we can't properly access arguments if the tracing >> > program is attached to extension program. >> > >> > Having following program: >> > >> > SEC("classifier/test_pkt_md_access") >> > int test_pkt_md_access(struct __sk_buff *skb) >> > >> > with its extension: >> > >> > SEC("freplace/test_pkt_md_access") >> > int test_pkt_md_access_new(struct __sk_buff *skb) >> > >> > and tracing that extension with: >> > >> > SEC("fentry/test_pkt_md_access_new") >> > int BPF_PROG(fentry, struct sk_buff *skb) >> > >> > It's not possible to access skb argument in the fentry program, >> > with following error from verifier: >> > >> > ; int BPF_PROG(fentry, struct sk_buff *skb) >> > 0: (79) r1 = *(u64 *)(r1 +0) >> > invalid bpf_context access off=0 size=8 >> > >> > The problem is that btf_ctx_access gets the context type for the >> > traced program, which is in this case the extension. >> > >> > But when we trace extension program, we want to get the context >> > type of the program that the extension is attached to, so we can >> > access the argument properly in the trace program. >> > >> > Reported-by: Eelco Chaudron <echaudro@redhat.com> >> > Signed-off-by: Jiri Olsa <jolsa@kernel.org> >> > --- >> > kernel/bpf/btf.c | 8 ++++++++ >> > 1 file changed, 8 insertions(+) >> > >> > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c >> > index f9ac6935ab3c..37ad01c32e5a 100644 >> > --- a/kernel/bpf/btf.c >> > +++ b/kernel/bpf/btf.c >> > @@ -3859,6 +3859,14 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type, >> > } >> > >> > info->reg_type = PTR_TO_BTF_ID; >> > + >> > + /* When we trace extension program, we want to get the context >> > + * type of the program that the extension is attached to, so >> > + * we can access the argument properly in the trace program. >> > + */ >> > + if (tgt_prog && tgt_prog->type == BPF_PROG_TYPE_EXT) >> > + tgt_prog = tgt_prog->aux->linked_prog; >> > + >> >> In the discussion about multi-attach for freplace we kinda concluded[0] >> that this linked_prog pointer was going away after attach. I have this >> basically working, but need to test a bit more before posting it (see >> [1] for current status). > > ok, feel free to use the test case from patch 2 ;-) > >> >> But with this I guess we'll need to either do something different? Maybe >> go chase down the target via the bpf_link or something? > > I'll check, could you please CC me on your next post? Sure, will do! -Toke ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: Fix context type resolving for extension programs 2020-09-09 15:11 [PATCH bpf-next 1/2] bpf: Fix context type resolving for extension programs Jiri Olsa 2020-09-09 15:11 ` [PATCH bpf-next 2/2] selftests/bpf: Adding test for arg dereference in extension trace Jiri Olsa 2020-09-09 15:54 ` [PATCH bpf-next 1/2] bpf: Fix context type resolving for extension programs Toke Høiland-Jørgensen @ 2020-09-10 18:00 ` Alexei Starovoitov 2020-09-11 10:52 ` Toke Høiland-Jørgensen 2 siblings, 1 reply; 10+ messages in thread From: Alexei Starovoitov @ 2020-09-10 18:00 UTC (permalink / raw) To: Jiri Olsa Cc: Alexei Starovoitov, Daniel Borkmann, Eelco Chaudron, Network Development, bpf, Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko, John Fastabend, KP Singh, Jesper Dangaard Brouer, Toke Høiland-Jørgensen On Wed, Sep 9, 2020 at 8:11 AM Jiri Olsa <jolsa@kernel.org> wrote: > > Eelco reported we can't properly access arguments if the tracing > program is attached to extension program. > > Having following program: > > SEC("classifier/test_pkt_md_access") > int test_pkt_md_access(struct __sk_buff *skb) > > with its extension: > > SEC("freplace/test_pkt_md_access") > int test_pkt_md_access_new(struct __sk_buff *skb) > > and tracing that extension with: > > SEC("fentry/test_pkt_md_access_new") > int BPF_PROG(fentry, struct sk_buff *skb) > > It's not possible to access skb argument in the fentry program, > with following error from verifier: > > ; int BPF_PROG(fentry, struct sk_buff *skb) > 0: (79) r1 = *(u64 *)(r1 +0) > invalid bpf_context access off=0 size=8 > > The problem is that btf_ctx_access gets the context type for the > traced program, which is in this case the extension. > > But when we trace extension program, we want to get the context > type of the program that the extension is attached to, so we can > access the argument properly in the trace program. > > Reported-by: Eelco Chaudron <echaudro@redhat.com> > Signed-off-by: Jiri Olsa <jolsa@kernel.org> > --- > kernel/bpf/btf.c | 8 ++++++++ > 1 file changed, 8 insertions(+) > > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c > index f9ac6935ab3c..37ad01c32e5a 100644 > --- a/kernel/bpf/btf.c > +++ b/kernel/bpf/btf.c > @@ -3859,6 +3859,14 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type, > } > > info->reg_type = PTR_TO_BTF_ID; > + > + /* When we trace extension program, we want to get the context > + * type of the program that the extension is attached to, so > + * we can access the argument properly in the trace program. > + */ > + if (tgt_prog && tgt_prog->type == BPF_PROG_TYPE_EXT) > + tgt_prog = tgt_prog->aux->linked_prog; > + > if (tgt_prog) { > ret = btf_translate_to_vmlinux(log, btf, t, tgt_prog->type, arg); I think it would be cleaner to move resolve_prog_type() from verifier.c and use that helper function here. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf: Fix context type resolving for extension programs 2020-09-10 18:00 ` Alexei Starovoitov @ 2020-09-11 10:52 ` Toke Høiland-Jørgensen 0 siblings, 0 replies; 10+ messages in thread From: Toke Høiland-Jørgensen @ 2020-09-11 10:52 UTC (permalink / raw) To: Alexei Starovoitov, Jiri Olsa Cc: Alexei Starovoitov, Daniel Borkmann, Eelco Chaudron, Network Development, bpf, Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko, John Fastabend, KP Singh, Jesper Dangaard Brouer Alexei Starovoitov <alexei.starovoitov@gmail.com> writes: > On Wed, Sep 9, 2020 at 8:11 AM Jiri Olsa <jolsa@kernel.org> wrote: >> >> Eelco reported we can't properly access arguments if the tracing >> program is attached to extension program. >> >> Having following program: >> >> SEC("classifier/test_pkt_md_access") >> int test_pkt_md_access(struct __sk_buff *skb) >> >> with its extension: >> >> SEC("freplace/test_pkt_md_access") >> int test_pkt_md_access_new(struct __sk_buff *skb) >> >> and tracing that extension with: >> >> SEC("fentry/test_pkt_md_access_new") >> int BPF_PROG(fentry, struct sk_buff *skb) >> >> It's not possible to access skb argument in the fentry program, >> with following error from verifier: >> >> ; int BPF_PROG(fentry, struct sk_buff *skb) >> 0: (79) r1 = *(u64 *)(r1 +0) >> invalid bpf_context access off=0 size=8 >> >> The problem is that btf_ctx_access gets the context type for the >> traced program, which is in this case the extension. >> >> But when we trace extension program, we want to get the context >> type of the program that the extension is attached to, so we can >> access the argument properly in the trace program. >> >> Reported-by: Eelco Chaudron <echaudro@redhat.com> >> Signed-off-by: Jiri Olsa <jolsa@kernel.org> >> --- >> kernel/bpf/btf.c | 8 ++++++++ >> 1 file changed, 8 insertions(+) >> >> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c >> index f9ac6935ab3c..37ad01c32e5a 100644 >> --- a/kernel/bpf/btf.c >> +++ b/kernel/bpf/btf.c >> @@ -3859,6 +3859,14 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type, >> } >> >> info->reg_type = PTR_TO_BTF_ID; >> + >> + /* When we trace extension program, we want to get the context >> + * type of the program that the extension is attached to, so >> + * we can access the argument properly in the trace program. >> + */ >> + if (tgt_prog && tgt_prog->type == BPF_PROG_TYPE_EXT) >> + tgt_prog = tgt_prog->aux->linked_prog; >> + >> if (tgt_prog) { >> ret = btf_translate_to_vmlinux(log, btf, t, tgt_prog->type, arg); > > I think it would be cleaner to move resolve_prog_type() from verifier.c > and use that helper function here. FYI, I've added a different version of this patch to my freplace multi-attach series (since the approach here was incompatible with that). -Toke ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2020-09-11 14:44 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-09-09 15:11 [PATCH bpf-next 1/2] bpf: Fix context type resolving for extension programs Jiri Olsa 2020-09-09 15:11 ` [PATCH bpf-next 2/2] selftests/bpf: Adding test for arg dereference in extension trace Jiri Olsa 2020-09-10 22:34 ` Andrii Nakryiko 2020-09-11 11:01 ` Toke Høiland-Jørgensen 2020-09-11 13:02 ` Jiri Olsa 2020-09-09 15:54 ` [PATCH bpf-next 1/2] bpf: Fix context type resolving for extension programs Toke Høiland-Jørgensen 2020-09-09 18:58 ` Jiri Olsa 2020-09-10 9:49 ` Toke Høiland-Jørgensen 2020-09-10 18:00 ` Alexei Starovoitov 2020-09-11 10:52 ` Toke Høiland-Jørgensen
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.