From: Jiri Olsa <jolsa@kernel.org>
To: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>
Cc: bpf@vger.kernel.org, Martin KaFai Lau <kafai@fb.com>,
Song Liu <songliubraving@fb.com>, Yonghong Song <yhs@fb.com>,
John Fastabend <john.fastabend@gmail.com>,
KP Singh <kpsingh@chromium.org>,
Stanislav Fomichev <sdf@google.com>, Hao Luo <haoluo@google.com>,
Yafang Shao <laoar.shao@gmail.com>
Subject: [PATCH bpf-next 5/6] selftests/bpf: Add link_info test for uprobe_multi link
Date: Wed, 25 Oct 2023 22:24:19 +0200 [thread overview]
Message-ID: <20231025202420.390702-6-jolsa@kernel.org> (raw)
In-Reply-To: <20231025202420.390702-1-jolsa@kernel.org>
Adding fill_link_info test for uprobe_multi link.
Setting up uprobes with bogus ref_ctr_offsets and cookie values
to test all the bpf_link_info::uprobe_multi fields.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
.../selftests/bpf/prog_tests/fill_link_info.c | 189 ++++++++++++++++++
.../selftests/bpf/progs/test_fill_link_info.c | 6 +
2 files changed, 195 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c
index 0379872c445a..96029fcbd47f 100644
--- a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c
+++ b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c
@@ -7,6 +7,7 @@
#include <test_progs.h>
#include "trace_helpers.h"
#include "test_fill_link_info.skel.h"
+#include "bpf/libbpf_internal.h"
#define TP_CAT "sched"
#define TP_NAME "sched_switch"
@@ -303,6 +304,187 @@ static void test_kprobe_multi_fill_link_info(struct test_fill_link_info *skel,
LINK_DESTROY(skel->links.kmulti_run);
}
+/* Initialize semaphore variables so they don't end up in bss
+ * section and we could get retrieve their offsets.
+ */
+static short uprobe_link_info_sema_1 = 1;
+static short uprobe_link_info_sema_2 = 1;
+static short uprobe_link_info_sema_3 = 1;
+
+noinline void uprobe_link_info_func_1(void)
+{
+ uprobe_link_info_sema_1++;
+ asm volatile ("");
+}
+
+noinline void uprobe_link_info_func_2(void)
+{
+ uprobe_link_info_sema_2++;
+ asm volatile ("");
+}
+
+noinline void uprobe_link_info_func_3(void)
+{
+ uprobe_link_info_sema_3++;
+ asm volatile ("");
+}
+
+static int
+verify_umulti_link_info(int fd, bool retprobe, int pid, __u64 *offsets,
+ __u64 *cookies, __u64 *ref_ctr_offsets)
+{
+ char path[PATH_MAX], path_buf[PATH_MAX];
+ struct bpf_link_info info;
+ __u32 len = sizeof(info);
+ __u64 ref_ctr_offsets_buf[3];
+ __u64 offsets_buf[3];
+ __u64 cookies_buf[3];
+ int i, err;
+
+ memset(path, 0, sizeof(path));
+ err = readlink("/proc/self/exe", path, sizeof(path));
+ if (!ASSERT_NEQ(err, -1, "readlink"))
+ return -1;
+
+ memset(&info, 0, sizeof(info));
+ info.uprobe_multi.path = ptr_to_u64(path_buf);
+ info.uprobe_multi.path_max = sizeof(path_buf);
+
+again:
+ err = bpf_link_get_info_by_fd(fd, &info, &len);
+ if (!ASSERT_OK(err, "bpf_link_get_info_by_fd"))
+ return -1;
+
+ if (!ASSERT_EQ(info.type, BPF_LINK_TYPE_UPROBE_MULTI, "info.type"))
+ return -1;
+
+ ASSERT_EQ(info.uprobe_multi.pid, pid ?: getpid(), "info.uprobe_multi.pid");
+ ASSERT_EQ(info.uprobe_multi.count, 3, "info.uprobe_multi.count");
+ ASSERT_EQ(info.uprobe_multi.flags & BPF_F_KPROBE_MULTI_RETURN,
+ retprobe, "info.uprobe_multi.flags.retprobe");
+ ASSERT_STREQ(path_buf, path, "info.uprobe_multi.path");
+
+ if (!info.uprobe_multi.offsets) {
+ info.uprobe_multi.offsets = ptr_to_u64(offsets_buf);
+ info.uprobe_multi.cookies = ptr_to_u64(cookies_buf);
+ info.uprobe_multi.ref_ctr_offsets = ptr_to_u64(ref_ctr_offsets_buf);
+ goto again;
+ }
+
+ for (i = 0; i < info.uprobe_multi.count; i++) {
+ ASSERT_EQ(offsets_buf[i], offsets[i], "info.uprobe_multi.offsets");
+ ASSERT_EQ(cookies_buf[i], cookies[i], "info.uprobe_multi.cookies");
+ ASSERT_EQ(ref_ctr_offsets_buf[i], ref_ctr_offsets[i], "info.uprobe_multi.ref_ctr_offsets");
+ }
+ return 0;
+}
+
+static void verify_umulti_invalid_user_buffer(int fd)
+{
+ struct bpf_link_info info;
+ __u32 len = sizeof(info);
+ char path[PATH_MAX + 1];
+ __u64 offsets[3];
+ int err;
+
+ // upath_max defined, not path
+ memset(&info, 0, sizeof(info));
+ info.uprobe_multi.path_max = 3;
+ err = bpf_link_get_info_by_fd(fd, &info, &len);
+ ASSERT_EQ(err, -EINVAL, "failed_upath_max");
+
+ // path has wrong pointer
+ memset(&info, 0, sizeof(info));
+ info.uprobe_multi.path_max = PATH_MAX;
+ info.uprobe_multi.path = 123;
+ err = bpf_link_get_info_by_fd(fd, &info, &len);
+ ASSERT_EQ(err, -EFAULT, "failed_bad_path_ptr");
+
+ // count defined, not offsets
+ memset(&info, 0, sizeof(info));
+ info.uprobe_multi.count = 3;
+ err = bpf_link_get_info_by_fd(fd, &info, &len);
+ ASSERT_EQ(err, -EINVAL, "failed_count");
+
+ // path_max too big
+ memset(&info, 0, sizeof(info));
+ info.uprobe_multi.path = ptr_to_u64(path);
+ info.uprobe_multi.path_max = sizeof(path);
+ err = bpf_link_get_info_by_fd(fd, &info, &len);
+ ASSERT_EQ(err, -E2BIG, "failed_path_max");
+
+ // offsets not big enough
+ memset(&info, 0, sizeof(info));
+ info.uprobe_multi.offsets = ptr_to_u64(offsets);
+ info.uprobe_multi.count = 2;
+ err = bpf_link_get_info_by_fd(fd, &info, &len);
+ ASSERT_EQ(err, -ENOSPC, "failed_small_count");
+
+ // offsets has wrong pointer
+ memset(&info, 0, sizeof(info));
+ info.uprobe_multi.offsets = 123;
+ info.uprobe_multi.count = 3;
+ err = bpf_link_get_info_by_fd(fd, &info, &len);
+ ASSERT_EQ(err, -EFAULT, "failed_wrong_offsets");
+}
+
+static void test_uprobe_multi_fill_link_info(struct test_fill_link_info *skel,
+ bool retprobe, bool invalid, int pid)
+{
+ LIBBPF_OPTS(bpf_uprobe_multi_opts, opts,
+ .retprobe = retprobe,
+ );
+ const char *syms[3] = {
+ "uprobe_link_info_func_1",
+ "uprobe_link_info_func_2",
+ "uprobe_link_info_func_3",
+ };
+ const char *sema[3] = {
+ "uprobe_link_info_sema_1",
+ "uprobe_link_info_sema_2",
+ "uprobe_link_info_sema_3",
+ };
+ __u64 cookies[3] = {
+ 0xdead,
+ 0xbeef,
+ 0xcafe,
+ };
+ __u64 *offsets, *ref_ctr_offsets;
+ int link_fd, err;
+
+ err = elf_resolve_syms_offsets("/proc/self/exe", 3, sema,
+ (unsigned long **) &ref_ctr_offsets, STT_OBJECT);
+ if (!ASSERT_OK(err, "elf_resolve_syms_offsets_object"))
+ return;
+
+ err = elf_resolve_syms_offsets("/proc/self/exe", 3, syms,
+ (unsigned long **) &offsets, STT_FUNC);
+ if (!ASSERT_OK(err, "elf_resolve_syms_offsets_func"))
+ return;
+
+ opts.syms = syms;
+ opts.cookies = &cookies[0];
+ opts.ref_ctr_offsets = (unsigned long *) &ref_ctr_offsets[0];
+ opts.cnt = ARRAY_SIZE(syms);
+
+ skel->links.umulti_run = bpf_program__attach_uprobe_multi(skel->progs.umulti_run, pid,
+ "/proc/self/exe", NULL, &opts);
+ if (!ASSERT_OK_PTR(skel->links.umulti_run, "bpf_program__attach_uprobe_multi"))
+ goto out;
+
+ link_fd = bpf_link__fd(skel->links.umulti_run);
+ if (invalid)
+ verify_umulti_invalid_user_buffer(link_fd);
+ else
+ verify_umulti_link_info(link_fd, retprobe, pid, offsets, cookies, ref_ctr_offsets);
+
+ LINK_DESTROY(skel->links.umulti_run);
+
+out:
+ free(ref_ctr_offsets);
+ free(offsets);
+}
+
void test_fill_link_info(void)
{
struct test_fill_link_info *skel;
@@ -342,6 +524,13 @@ void test_fill_link_info(void)
if (test__start_subtest("kprobe_multi_invalid_ubuff"))
test_kprobe_multi_fill_link_info(skel, true, true);
+ if (test__start_subtest("uprobe_multi_link_info"))
+ test_uprobe_multi_fill_link_info(skel, false, false, -1);
+ if (test__start_subtest("uretprobe_multi_link_info"))
+ test_uprobe_multi_fill_link_info(skel, true, false, 0);
+ if (test__start_subtest("uprobe_multi_invalid"))
+ test_uprobe_multi_fill_link_info(skel, false, true, -1);
+
cleanup:
test_fill_link_info__destroy(skel);
}
diff --git a/tools/testing/selftests/bpf/progs/test_fill_link_info.c b/tools/testing/selftests/bpf/progs/test_fill_link_info.c
index 564f402d56fe..69509f8bb680 100644
--- a/tools/testing/selftests/bpf/progs/test_fill_link_info.c
+++ b/tools/testing/selftests/bpf/progs/test_fill_link_info.c
@@ -39,4 +39,10 @@ int BPF_PROG(kmulti_run)
return 0;
}
+SEC("uprobe.multi")
+int BPF_PROG(umulti_run)
+{
+ return 0;
+}
+
char _license[] SEC("license") = "GPL";
--
2.41.0
next prev parent reply other threads:[~2023-10-25 20:25 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-25 20:24 [PATCH bpf-next 0/6] bpf: Add link_info support for uprobe multi link Jiri Olsa
2023-10-25 20:24 ` [PATCH bpf-next 1/6] libbpf: Add st_type argument to elf_resolve_syms_offsets function Jiri Olsa
2023-10-26 16:29 ` Song Liu
2023-10-25 20:24 ` [PATCH bpf-next 2/6] bpf: Store ref_ctr_offsets values in bpf_uprobe array Jiri Olsa
2023-10-26 16:31 ` Song Liu
2023-10-27 13:56 ` Jiri Olsa
2023-10-27 14:23 ` Song Liu
2023-11-01 22:21 ` Andrii Nakryiko
2023-10-25 20:24 ` [PATCH bpf-next 3/6] bpf: Add link_info support for uprobe multi link Jiri Olsa
2023-10-26 11:57 ` Yafang Shao
2023-10-27 13:59 ` Jiri Olsa
2023-11-09 8:56 ` Jiri Olsa
2023-10-26 17:55 ` Song Liu
2023-10-27 14:29 ` Jiri Olsa
2023-11-01 22:21 ` Andrii Nakryiko
2023-11-02 14:58 ` Jiri Olsa
2023-11-02 16:21 ` Andrii Nakryiko
2023-10-30 10:18 ` Quentin Monnet
2023-10-30 21:17 ` Jiri Olsa
2023-11-01 22:21 ` Andrii Nakryiko
2023-11-02 14:43 ` Jiri Olsa
2023-11-02 16:19 ` Andrii Nakryiko
2023-10-25 20:24 ` [PATCH bpf-next 4/6] selftests/bpf: Use bpf_link__destroy in fill_link_info tests Jiri Olsa
2023-10-26 11:41 ` Yafang Shao
2023-10-26 18:00 ` Song Liu
2023-11-01 22:24 ` Andrii Nakryiko
2023-11-02 14:12 ` Jiri Olsa
2023-10-25 20:24 ` Jiri Olsa [this message]
2023-10-26 18:13 ` [PATCH bpf-next 5/6] selftests/bpf: Add link_info test for uprobe_multi link Song Liu
2023-11-01 22:27 ` Andrii Nakryiko
2023-10-25 20:24 ` [PATCH bpf-next 6/6] bpftool: Add support to display uprobe_multi links Jiri Olsa
2023-10-26 18:27 ` Song Liu
2023-10-30 10:17 ` Quentin Monnet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231025202420.390702-6-jolsa@kernel.org \
--to=jolsa@kernel.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=haoluo@google.com \
--cc=john.fastabend@gmail.com \
--cc=kafai@fb.com \
--cc=kpsingh@chromium.org \
--cc=laoar.shao@gmail.com \
--cc=sdf@google.com \
--cc=songliubraving@fb.com \
--cc=yhs@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox