From patchwork Wed Oct 25 20:24:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13436702 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A5BDB33983 for ; Wed, 25 Oct 2023 20:24:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KpEcN0XY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 40FC2C433AD; Wed, 25 Oct 2023 20:24:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698265477; bh=cIv5homO8PHkmQzVTm+un37Xtgymlp/MhDG4LldjDio=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KpEcN0XYWVsLMkrtDtjoEsl2a+lUh3K4D7CbYgdMuc58z8HRT/JuBKf7/PKVaj4ok MMn/ylKIFjRIltXyp7CDpe81gyDlbplKKhkn108Z/k8jfUCtLNS5z+4Fe5t95OGBIT WfXpDf3YmweokzOQGBzOpz+r9JDeRE0bfB0BSQeRuRB04ZUsLRplhE7XRC5Z/iRKIr fxLR5dGUHldmIZ9RwxnRp7K7RSSk6nsynYBRBmBo8HZ1K1X4mA7yFjFRqndzxJG80v caCjUysAMYRTNwO0NI+/QgOk+q3vl1aysI/6GhOom7VOv0xu456FuJzd2H8p94xZwE DPo5L/yl+0UNA== From: Jiri Olsa To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko Cc: bpf@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Yafang Shao Subject: [PATCH bpf-next 1/6] libbpf: Add st_type argument to elf_resolve_syms_offsets function Date: Wed, 25 Oct 2023 22:24:15 +0200 Message-ID: <20231025202420.390702-2-jolsa@kernel.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231025202420.390702-1-jolsa@kernel.org> References: <20231025202420.390702-1-jolsa@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net We need to get offsets for static variables in following changes, so making elf_resolve_syms_offsets to take st_type value as argument and passing it to elf_sym_iter_new. Signed-off-by: Jiri Olsa Acked-by: Song Liu --- tools/lib/bpf/elf.c | 5 +++-- tools/lib/bpf/libbpf.c | 2 +- tools/lib/bpf/libbpf_internal.h | 3 ++- tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/lib/bpf/elf.c b/tools/lib/bpf/elf.c index 2a62bf411bb3..b02faec748a5 100644 --- a/tools/lib/bpf/elf.c +++ b/tools/lib/bpf/elf.c @@ -407,7 +407,8 @@ static int symbol_cmp(const void *a, const void *b) * size, that needs to be released by the caller. */ int elf_resolve_syms_offsets(const char *binary_path, int cnt, - const char **syms, unsigned long **poffsets) + const char **syms, unsigned long **poffsets, + int st_type) { int sh_types[2] = { SHT_DYNSYM, SHT_SYMTAB }; int err = 0, i, cnt_done = 0; @@ -438,7 +439,7 @@ int elf_resolve_syms_offsets(const char *binary_path, int cnt, struct elf_sym_iter iter; struct elf_sym *sym; - err = elf_sym_iter_new(&iter, elf_fd.elf, binary_path, sh_types[i], STT_FUNC); + err = elf_sym_iter_new(&iter, elf_fd.elf, binary_path, sh_types[i], st_type); if (err == -ENOENT) continue; if (err) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index e067be95da3c..ea9b8158c20d 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -11447,7 +11447,7 @@ bpf_program__attach_uprobe_multi(const struct bpf_program *prog, return libbpf_err_ptr(err); offsets = resolved_offsets; } else if (syms) { - err = elf_resolve_syms_offsets(path, cnt, syms, &resolved_offsets); + err = elf_resolve_syms_offsets(path, cnt, syms, &resolved_offsets, STT_FUNC); if (err < 0) return libbpf_err_ptr(err); offsets = resolved_offsets; diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h index f0f08635adb0..b5d334754e5d 100644 --- a/tools/lib/bpf/libbpf_internal.h +++ b/tools/lib/bpf/libbpf_internal.h @@ -594,7 +594,8 @@ int elf_open(const char *binary_path, struct elf_fd *elf_fd); void elf_close(struct elf_fd *elf_fd); int elf_resolve_syms_offsets(const char *binary_path, int cnt, - const char **syms, unsigned long **poffsets); + const char **syms, unsigned long **poffsets, + int st_type); int elf_resolve_pattern_offsets(const char *binary_path, const char *pattern, unsigned long **poffsets, size_t *pcnt); diff --git a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c index cd051d3901a9..ece260cf2c0b 100644 --- a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c +++ b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c @@ -249,7 +249,7 @@ static void __test_link_api(struct child *child) int link_extra_fd = -1; int err; - err = elf_resolve_syms_offsets(path, 3, syms, (unsigned long **) &offsets); + err = elf_resolve_syms_offsets(path, 3, syms, (unsigned long **) &offsets, STT_FUNC); if (!ASSERT_OK(err, "elf_resolve_syms_offsets")) return; From patchwork Wed Oct 25 20:24:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13436703 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 366FD33985 for ; Wed, 25 Oct 2023 20:24:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="CrbQNkwu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CA24EC433CD; Wed, 25 Oct 2023 20:24:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698265487; bh=vH8nsoAQOvrBMwN1O6dKA5iud+7mS/GBe5atb7Vcstg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CrbQNkwu7+8P3dEJg5zHbTOqlEXjMAh+QdmfKUA/SgtcR8dD/rtJMig843UFrFMWN fvaFU3ENMt3n8GitNNBzGOf2C0mgqMvHA4t6vgFYQS/Btnoff7TFMR0KAJXvb9TZPv svicoHsnfO5620b4lso1l49oxbEjBwsqVWtNk0eRUYOnqCF9458o6vumYfvPBI3uFa /yey3vmmlIjMy81fjg884GvR8WwZZo62cH+PlBvPJOatYBo0LEY/IzQmhIhJwwoGwi hpxVKDRQMlZnJWR9eo9reRD5tdF7LUAkKG4kVoE2YfzM0lsS1Gk3X5rnqz67WTEsQF qNwcFMXoQ5tAw== From: Jiri Olsa To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko Cc: bpf@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Yafang Shao Subject: [PATCH bpf-next 2/6] bpf: Store ref_ctr_offsets values in bpf_uprobe array Date: Wed, 25 Oct 2023 22:24:16 +0200 Message-ID: <20231025202420.390702-3-jolsa@kernel.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231025202420.390702-1-jolsa@kernel.org> References: <20231025202420.390702-1-jolsa@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net We will need to return ref_ctr_offsets values through link_info interface in following change, so we need to keep them around. Storing ref_ctr_offsets values directly into bpf_uprobe array. Signed-off-by: Jiri Olsa Acked-by: Song Liu --- kernel/trace/bpf_trace.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index df697c74d519..843b3846d3f8 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -3031,6 +3031,7 @@ struct bpf_uprobe_multi_link; struct bpf_uprobe { struct bpf_uprobe_multi_link *link; loff_t offset; + unsigned long ref_ctr_offset; u64 cookie; struct uprobe_consumer consumer; }; @@ -3170,7 +3171,6 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr { struct bpf_uprobe_multi_link *link = NULL; unsigned long __user *uref_ctr_offsets; - unsigned long *ref_ctr_offsets = NULL; struct bpf_link_primer link_primer; struct bpf_uprobe *uprobes = NULL; struct task_struct *task = NULL; @@ -3243,18 +3243,12 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr if (!uprobes || !link) goto error_free; - if (uref_ctr_offsets) { - ref_ctr_offsets = kvcalloc(cnt, sizeof(*ref_ctr_offsets), GFP_KERNEL); - if (!ref_ctr_offsets) - goto error_free; - } - for (i = 0; i < cnt; i++) { if (ucookies && __get_user(uprobes[i].cookie, ucookies + i)) { err = -EFAULT; goto error_free; } - if (uref_ctr_offsets && __get_user(ref_ctr_offsets[i], uref_ctr_offsets + i)) { + if (uref_ctr_offsets && __get_user(uprobes[i].ref_ctr_offset, uref_ctr_offsets + i)) { err = -EFAULT; goto error_free; } @@ -3285,7 +3279,7 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr for (i = 0; i < cnt; i++) { err = uprobe_register_refctr(d_real_inode(link->path.dentry), uprobes[i].offset, - ref_ctr_offsets ? ref_ctr_offsets[i] : 0, + uprobes[i].ref_ctr_offset, &uprobes[i].consumer); if (err) { bpf_uprobe_unregister(&path, uprobes, i); @@ -3297,11 +3291,9 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr if (err) goto error_free; - kvfree(ref_ctr_offsets); return bpf_link_settle(&link_primer); error_free: - kvfree(ref_ctr_offsets); kvfree(uprobes); kfree(link); if (task) From patchwork Wed Oct 25 20:24:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13436704 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A08B33983 for ; Wed, 25 Oct 2023 20:24:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZmXMxGAe" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 37AD3C433C8; Wed, 25 Oct 2023 20:24:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698265498; bh=2Y0Gi0ZF8V4rstyRh9mQN9eOaXDtx06DFHdNVyOgh20=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZmXMxGAes2askKqdCg03lZm8nKnN0ZaWUUTlrFkxnfiI7YF7pqu0a51cg7/OOl0kh AJjvKijjAGNwclfJVUeyFtQsoKZvjIvrMcfBZtgOjLqCXUndaGLnQ93kTok8fk2DeB X3gBF1EzozDnw+nahRe3kn3DI8q+zwHNdIzsrgcRY4njSEBHOyqQnpslbMXvUNnnk6 LgsayZZR2g9RmkgJqtdCf+zGwVK4jll2KuCfbh6/4haQ7gErUZR+ISSS0GZDUkwnAP unlKTin17cm6MjQEZyFQgaoaA7MJOpVjSlpdz7Xs68Aa3z4ekYiBOieZnYCZz7qUhC f7chdHfwzsWJQ== From: Jiri Olsa To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko Cc: bpf@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Yafang Shao Subject: [PATCH bpf-next 3/6] bpf: Add link_info support for uprobe multi link Date: Wed, 25 Oct 2023 22:24:17 +0200 Message-ID: <20231025202420.390702-4-jolsa@kernel.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231025202420.390702-1-jolsa@kernel.org> References: <20231025202420.390702-1-jolsa@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Adding support to get uprobe_link details through bpf_link_info interface. Adding new struct uprobe_multi to struct bpf_link_info to carry the uprobe_multi link details. The uprobe_multi.count is passed from user space to denote size of array fields (offsets/ref_ctr_offsets/cookies). The actual array size is stored back to uprobe_multi.count (allowing user to find out the actual array size) and array fields are populated up to the user passed size. All the non-array fields (path/count/flags/pid) are always set. Signed-off-by: Jiri Olsa --- include/uapi/linux/bpf.h | 10 +++++ kernel/trace/bpf_trace.c | 68 ++++++++++++++++++++++++++++++++++ tools/include/uapi/linux/bpf.h | 10 +++++ 3 files changed, 88 insertions(+) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 0f6cdf52b1da..960cf2914d63 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -6556,6 +6556,16 @@ struct bpf_link_info { __u32 flags; __u64 missed; } kprobe_multi; + struct { + __aligned_u64 path; + __aligned_u64 offsets; + __aligned_u64 ref_ctr_offsets; + __aligned_u64 cookies; + __u32 path_max; /* in/out: uprobe_multi path size */ + __u32 count; /* in/out: uprobe_multi offsets/ref_ctr_offsets/cookies count */ + __u32 flags; + __u32 pid; + } uprobe_multi; struct { __u32 type; /* enum bpf_perf_event_type */ __u32 :32; diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 843b3846d3f8..9f8ad19a1a93 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -3042,6 +3042,7 @@ struct bpf_uprobe_multi_link { u32 cnt; struct bpf_uprobe *uprobes; struct task_struct *task; + u32 flags; }; struct bpf_uprobe_multi_run_ctx { @@ -3081,9 +3082,75 @@ static void bpf_uprobe_multi_link_dealloc(struct bpf_link *link) kfree(umulti_link); } +static int bpf_uprobe_multi_link_fill_link_info(const struct bpf_link *link, + struct bpf_link_info *info) +{ + u64 __user *uref_ctr_offsets = u64_to_user_ptr(info->uprobe_multi.ref_ctr_offsets); + u64 __user *ucookies = u64_to_user_ptr(info->uprobe_multi.cookies); + u64 __user *uoffsets = u64_to_user_ptr(info->uprobe_multi.offsets); + u64 __user *upath = u64_to_user_ptr(info->uprobe_multi.path); + u32 upath_max = info->uprobe_multi.path_max; + struct bpf_uprobe_multi_link *umulti_link; + u32 ucount = info->uprobe_multi.count; + int err = 0, i; + char *p, *buf; + long left; + + if (!upath ^ !upath_max) + return -EINVAL; + + if (!uoffsets ^ !ucount) + return -EINVAL; + + umulti_link = container_of(link, struct bpf_uprobe_multi_link, link); + info->uprobe_multi.count = umulti_link->cnt; + info->uprobe_multi.flags = umulti_link->flags; + info->uprobe_multi.pid = umulti_link->task ? + task_pid_nr(umulti_link->task) : (u32) -1; + + if (upath) { + if (upath_max > PATH_MAX) + return -E2BIG; + buf = kmalloc(upath_max, GFP_KERNEL); + if (!buf) + return -ENOMEM; + p = d_path(&umulti_link->path, buf, upath_max); + if (IS_ERR(p)) { + kfree(buf); + return -ENOSPC; + } + left = copy_to_user(upath, p, buf + upath_max - p); + kfree(buf); + if (left) + return -EFAULT; + } + + if (!uoffsets) + return 0; + + if (ucount < umulti_link->cnt) + err = -ENOSPC; + else + ucount = umulti_link->cnt; + + for (i = 0; i < ucount; i++) { + if (put_user(umulti_link->uprobes[i].offset, uoffsets + i)) + return -EFAULT; + if (uref_ctr_offsets && + put_user(umulti_link->uprobes[i].ref_ctr_offset, uref_ctr_offsets + i)) + return -EFAULT; + if (ucookies && + put_user(umulti_link->uprobes[i].cookie, ucookies + i)) + return -EFAULT; + } + + return err; +} + static const struct bpf_link_ops bpf_uprobe_multi_link_lops = { .release = bpf_uprobe_multi_link_release, .dealloc = bpf_uprobe_multi_link_dealloc, + .fill_link_info = bpf_uprobe_multi_link_fill_link_info, }; static int uprobe_prog_run(struct bpf_uprobe *uprobe, @@ -3272,6 +3339,7 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr link->uprobes = uprobes; link->path = path; link->task = task; + link->flags = flags; bpf_link_init(&link->link, BPF_LINK_TYPE_UPROBE_MULTI, &bpf_uprobe_multi_link_lops, prog); diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 0f6cdf52b1da..960cf2914d63 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -6556,6 +6556,16 @@ struct bpf_link_info { __u32 flags; __u64 missed; } kprobe_multi; + struct { + __aligned_u64 path; + __aligned_u64 offsets; + __aligned_u64 ref_ctr_offsets; + __aligned_u64 cookies; + __u32 path_max; /* in/out: uprobe_multi path size */ + __u32 count; /* in/out: uprobe_multi offsets/ref_ctr_offsets/cookies count */ + __u32 flags; + __u32 pid; + } uprobe_multi; struct { __u32 type; /* enum bpf_perf_event_type */ __u32 :32; From patchwork Wed Oct 25 20:24:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13436705 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 571EE3398B for ; Wed, 25 Oct 2023 20:25:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HW3W0MiA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E6A61C433C8; Wed, 25 Oct 2023 20:25:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698265508; bh=d1xVG+KpucDtyaWtSPlpmGw9SfRaMtX90wnctNfV+Is=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HW3W0MiA0wepPrEiTPcfDHTHXSlUVBDOUsHswwWWGeMYHPdVD64LgCNZBC+Ndpkeo hVoWXQDMSDYk3JvzmX9jAUsGgYlnz1h27cmmgPvRkm+EioInmWcOomWO5MJ3j4bD0t 4GrTIpDMIO0/pNfJMf1qPE+sHfG/r1+UHEU9AevdVEUXN6wGMyIGZb/z2j8Vrgm03/ LtoxflnDNkh7FT9DSntXIJtEtq/HZUSES8vJGdXpQJVlo0D2QlhBOWd7fBnP9K/Wi4 4a8b33o9u9hTeMq2GUT+QLOGcoIVqkuetO1nOo3MikA/EiAg6i97DASwkf4KMVI4dT 69sjX9ecWv2TA== From: Jiri Olsa To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko Cc: bpf@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Yafang Shao Subject: [PATCH bpf-next 4/6] selftests/bpf: Use bpf_link__destroy in fill_link_info tests Date: Wed, 25 Oct 2023 22:24:18 +0200 Message-ID: <20231025202420.390702-5-jolsa@kernel.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231025202420.390702-1-jolsa@kernel.org> References: <20231025202420.390702-1-jolsa@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net The fill_link_info test keeps skeleton open and just creates various links. We are wrongly calling bpf_link__detach after each test to close them, we need to call bpf_link__destroy. Also we need to set the link NULL so the skeleton destroy won't try to destroy them again. Signed-off-by: Jiri Olsa Acked-by: Yafang Shao Acked-by: Song Liu --- .../selftests/bpf/prog_tests/fill_link_info.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) 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 97142a4db374..0379872c445a 100644 --- a/tools/testing/selftests/bpf/prog_tests/fill_link_info.c +++ b/tools/testing/selftests/bpf/prog_tests/fill_link_info.c @@ -22,6 +22,11 @@ static __u64 kmulti_addrs[KMULTI_CNT]; #define KPROBE_FUNC "bpf_fentry_test1" static __u64 kprobe_addr; +#define LINK_DESTROY(__link) ({ \ + bpf_link__destroy(__link); \ + __link = NULL; \ +}) + #define UPROBE_FILE "/proc/self/exe" static ssize_t uprobe_offset; /* uprobe attach point */ @@ -157,7 +162,7 @@ static void test_kprobe_fill_link_info(struct test_fill_link_info *skel, } else { kprobe_fill_invalid_user_buffer(link_fd); } - bpf_link__detach(skel->links.kprobe_run); + LINK_DESTROY(skel->links.kprobe_run); } static void test_tp_fill_link_info(struct test_fill_link_info *skel) @@ -171,7 +176,7 @@ static void test_tp_fill_link_info(struct test_fill_link_info *skel) link_fd = bpf_link__fd(skel->links.tp_run); err = verify_perf_link_info(link_fd, BPF_PERF_EVENT_TRACEPOINT, 0, 0, 0); ASSERT_OK(err, "verify_perf_link_info"); - bpf_link__detach(skel->links.tp_run); + LINK_DESTROY(skel->links.tp_run); } static void test_uprobe_fill_link_info(struct test_fill_link_info *skel, @@ -189,7 +194,7 @@ static void test_uprobe_fill_link_info(struct test_fill_link_info *skel, link_fd = bpf_link__fd(skel->links.uprobe_run); err = verify_perf_link_info(link_fd, type, 0, uprobe_offset, 0); ASSERT_OK(err, "verify_perf_link_info"); - bpf_link__detach(skel->links.uprobe_run); + LINK_DESTROY(skel->links.uprobe_run); } static int verify_kmulti_link_info(int fd, bool retprobe) @@ -295,7 +300,7 @@ static void test_kprobe_multi_fill_link_info(struct test_fill_link_info *skel, } else { verify_kmulti_invalid_user_buffer(link_fd); } - bpf_link__detach(skel->links.kmulti_run); + LINK_DESTROY(skel->links.kmulti_run); } void test_fill_link_info(void) From patchwork Wed Oct 25 20:24:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13436706 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5ADB933983 for ; Wed, 25 Oct 2023 20:25:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fddr/VX2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3C18BC433C7; Wed, 25 Oct 2023 20:25:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698265519; bh=xtmS0XbrKPLTZ+z2wFoiDq8KuajpJi8ax2QHWbbrhOE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fddr/VX2dGpmxSbwVBPy10cBdxsbt+gy6iUK7CRx7h9BL7RuMw2JnoElZHTTnsHE8 Wzcm3a4rOYchmqtLAeea4+XUaSmL+gkbPiSvkMs+Ksu2iMDc7K1ayMVZCGR10zz8FU INg2Wo5YXhwlYqpSO2LdzCJ/k+z07MFDipS3IeN0DSxPq5h5DyCCt4ss3iayRLadHX QkA18VvrUVPy5pd/ZX9kA33TT1A93CoupmsrMOOwcVxYffu7vYMV8nBrxt3/J3ehC+ 6CXxdEPQ3CNEngffSo3QyG8dxBKU1iewPOxoDphIM+b/kvwS6sK63hIlkFGZOcjbNW Zl20MhJm9Na5Q== From: Jiri Olsa To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko Cc: bpf@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Yafang Shao 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 Message-ID: <20231025202420.390702-6-jolsa@kernel.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231025202420.390702-1-jolsa@kernel.org> References: <20231025202420.390702-1-jolsa@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net 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 Acked-by: Song Liu --- .../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 #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"; From patchwork Wed Oct 25 20:24:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 13436707 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BF355339A2 for ; Wed, 25 Oct 2023 20:25:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="G6Dc6jt2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A8B12C433C8; Wed, 25 Oct 2023 20:25:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698265529; bh=wOTroeYF7PUN0iWSBhXLoOawSgiQVYR0eYD9q807u8E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=G6Dc6jt2StdmUSvILsefMvxIU4UW5+ANQDzw5MzKi0eoILFu3csGlB9Cau2f7YTeo PwWwz9zeW+PF0+T1tgF5AgNF93yA4vIYyUAhodX0wzeMsSRDVvTiSfxvQXvjNorq5O vGKwAP/A+fXBuLLZ3Z9+J7b0weyXOmTkLA6qJELh1dAO93z8MU2OjNAAjSZZSzye0a mm4Mb0ayV5c633w86013tEgatbbQkT//LQ/0W/fnT/1D2fgxyW5Vs3isNdWNzTBodF /3gLgKM0vYkof7VwgtAm1qCUx6QERRScn+YHtW9tHyny5ONYOll9JcP+0detM2uzgI z+RYW7010EvAQ== From: Jiri Olsa To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko Cc: bpf@vger.kernel.org, Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Yafang Shao Subject: [PATCH bpf-next 6/6] bpftool: Add support to display uprobe_multi links Date: Wed, 25 Oct 2023 22:24:20 +0200 Message-ID: <20231025202420.390702-7-jolsa@kernel.org> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231025202420.390702-1-jolsa@kernel.org> References: <20231025202420.390702-1-jolsa@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Adding support to display details for uprobe_multi links, both plain: # bpftool link -p ... 24: uprobe_multi prog 126 uprobe.multi path /home/jolsa/bpf/test_progs func_cnt 3 pid 4143 offset ref_ctr_offset cookies 0xd1f88 0xf5d5a8 0xdead 0xd1f8f 0xf5d5aa 0xbeef 0xd1f96 0xf5d5ac 0xcafe and json: # bpftool link -p | jq [{ ... },{ "id": 24, "type": "uprobe_multi", "prog_id": 126, "retprobe": false, "path": "/home/jolsa/bpf/test_progs", "func_cnt": 3, "pid": 4143, "funcs": [{ "offset": 860040, "ref_ctr_offset": 16111016, "cookie": 57005 },{ "offset": 860047, "ref_ctr_offset": 16111018, "cookie": 48879 },{ "offset": 860054, "ref_ctr_offset": 16111020, "cookie": 51966 } ] } ] Signed-off-by: Jiri Olsa Acked-by: Song Liu Reviewed-by: Quentin Monnet --- tools/bpf/bpftool/link.c | 102 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 2 deletions(-) diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c index a1528cde81ab..21c7e4f038c4 100644 --- a/tools/bpf/bpftool/link.c +++ b/tools/bpf/bpftool/link.c @@ -294,6 +294,34 @@ show_kprobe_multi_json(struct bpf_link_info *info, json_writer_t *wtr) jsonw_end_array(json_wtr); } +#define U64_PTR(__val) ((__u64 *) u64_to_ptr(__val)) + +static void +show_uprobe_multi_json(struct bpf_link_info *info, json_writer_t *wtr) +{ + __u32 i; + + jsonw_bool_field(json_wtr, "retprobe", + info->uprobe_multi.flags & BPF_F_UPROBE_MULTI_RETURN); + jsonw_string_field(json_wtr, "path", (char *) u64_to_ptr(info->uprobe_multi.path)); + jsonw_uint_field(json_wtr, "func_cnt", info->uprobe_multi.count); + jsonw_int_field(json_wtr, "pid", (int) info->uprobe_multi.pid); + jsonw_name(json_wtr, "funcs"); + jsonw_start_array(json_wtr); + + for (i = 0; i < info->uprobe_multi.count; i++) { + jsonw_start_object(json_wtr); + jsonw_uint_field(json_wtr, "offset", + U64_PTR(info->uprobe_multi.offsets)[i]); + jsonw_uint_field(json_wtr, "ref_ctr_offset", + U64_PTR(info->uprobe_multi.ref_ctr_offsets)[i]); + jsonw_uint_field(json_wtr, "cookie", + U64_PTR(info->uprobe_multi.cookies)[i]); + jsonw_end_object(json_wtr); + } + jsonw_end_array(json_wtr); +} + static void show_perf_event_kprobe_json(struct bpf_link_info *info, json_writer_t *wtr) { @@ -465,6 +493,9 @@ static int show_link_close_json(int fd, struct bpf_link_info *info) case BPF_LINK_TYPE_KPROBE_MULTI: show_kprobe_multi_json(info, json_wtr); break; + case BPF_LINK_TYPE_UPROBE_MULTI: + show_uprobe_multi_json(info, json_wtr); + break; case BPF_LINK_TYPE_PERF_EVENT: switch (info->perf_event.type) { case BPF_PERF_EVENT_EVENT: @@ -674,6 +705,33 @@ static void show_kprobe_multi_plain(struct bpf_link_info *info) } } +static void show_uprobe_multi_plain(struct bpf_link_info *info) +{ + __u32 i; + + if (!info->uprobe_multi.count) + return; + + if (info->uprobe_multi.flags & BPF_F_UPROBE_MULTI_RETURN) + printf("\n\turetprobe.multi "); + else + printf("\n\tuprobe.multi "); + + printf("path %s ", (char *) u64_to_ptr(info->uprobe_multi.path)); + printf("func_cnt %u ", info->uprobe_multi.count); + + if (info->uprobe_multi.pid != (__u32) -1) + printf("pid %d ", info->uprobe_multi.pid); + + printf("\n\t%-16s %-16s %-16s", "offset", "ref_ctr_offset", "cookies"); + for (i = 0; i < info->uprobe_multi.count; i++) { + printf("\n\t0x%-16llx 0x%-16llx 0x%-16llx", + U64_PTR(info->uprobe_multi.offsets)[i], + U64_PTR(info->uprobe_multi.ref_ctr_offsets)[i], + U64_PTR(info->uprobe_multi.cookies)[i]); + } +} + static void show_perf_event_kprobe_plain(struct bpf_link_info *info) { const char *buf; @@ -807,6 +865,9 @@ static int show_link_close_plain(int fd, struct bpf_link_info *info) case BPF_LINK_TYPE_KPROBE_MULTI: show_kprobe_multi_plain(info); break; + case BPF_LINK_TYPE_UPROBE_MULTI: + show_uprobe_multi_plain(info); + break; case BPF_LINK_TYPE_PERF_EVENT: switch (info->perf_event.type) { case BPF_PERF_EVENT_EVENT: @@ -846,8 +907,10 @@ static int show_link_close_plain(int fd, struct bpf_link_info *info) static int do_show_link(int fd) { + __u64 *ref_ctr_offsets = NULL, *offsets = NULL, *cookies = NULL; struct bpf_link_info info; __u32 len = sizeof(info); + char path_buf[PATH_MAX]; __u64 *addrs = NULL; char buf[PATH_MAX]; int count; @@ -889,6 +952,39 @@ static int do_show_link(int fd) goto again; } } + if (info.type == BPF_LINK_TYPE_UPROBE_MULTI && + !info.uprobe_multi.offsets) { + count = info.uprobe_multi.count; + if (count) { + offsets = calloc(count, sizeof(__u64)); + if (!offsets) { + p_err("mem alloc failed"); + close(fd); + return -ENOMEM; + } + info.uprobe_multi.offsets = ptr_to_u64(offsets); + ref_ctr_offsets = calloc(count, sizeof(__u64)); + if (!ref_ctr_offsets) { + p_err("mem alloc failed"); + free(offsets); + close(fd); + return -ENOMEM; + } + info.uprobe_multi.ref_ctr_offsets = ptr_to_u64(ref_ctr_offsets); + cookies = calloc(count, sizeof(__u64)); + if (!cookies) { + p_err("mem alloc failed"); + free(cookies); + free(offsets); + close(fd); + return -ENOMEM; + } + info.uprobe_multi.cookies = ptr_to_u64(cookies); + info.uprobe_multi.path = ptr_to_u64(path_buf); + info.uprobe_multi.path_max = sizeof(path_buf); + goto again; + } + } if (info.type == BPF_LINK_TYPE_PERF_EVENT) { switch (info.perf_event.type) { case BPF_PERF_EVENT_TRACEPOINT: @@ -924,8 +1020,10 @@ static int do_show_link(int fd) else show_link_close_plain(fd, &info); - if (addrs) - free(addrs); + free(ref_ctr_offsets); + free(cookies); + free(offsets); + free(addrs); close(fd); return 0; }