Commit 7ac8d0d2 authored by Yafang Shao's avatar Yafang Shao Committed by Alexei Starovoitov

bpf: Support ->fill_link_info for kprobe_multi

With the addition of support for fill_link_info to the kprobe_multi link,
users will gain the ability to inspect it conveniently using the
`bpftool link show`. This enhancement provides valuable information to the
user, including the count of probed functions and their respective
addresses. It's important to note that if the kptr_restrict setting is not
permitted, the probed address will not be exposed, ensuring security.
Signed-off-by: default avatarYafang Shao <laoar.shao@gmail.com>
Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20230709025630.3735-2-laoar.shao@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 07018b57
...@@ -6439,6 +6439,11 @@ struct bpf_link_info { ...@@ -6439,6 +6439,11 @@ struct bpf_link_info {
__s32 priority; __s32 priority;
__u32 flags; __u32 flags;
} netfilter; } netfilter;
struct {
__aligned_u64 addrs;
__u32 count; /* in/out: kprobe_multi function count */
__u32 flags;
} kprobe_multi;
}; };
} __attribute__((aligned(8))); } __attribute__((aligned(8)));
......
...@@ -2469,6 +2469,7 @@ struct bpf_kprobe_multi_link { ...@@ -2469,6 +2469,7 @@ struct bpf_kprobe_multi_link {
u32 cnt; u32 cnt;
u32 mods_cnt; u32 mods_cnt;
struct module **mods; struct module **mods;
u32 flags;
}; };
struct bpf_kprobe_multi_run_ctx { struct bpf_kprobe_multi_run_ctx {
...@@ -2558,9 +2559,44 @@ static void bpf_kprobe_multi_link_dealloc(struct bpf_link *link) ...@@ -2558,9 +2559,44 @@ static void bpf_kprobe_multi_link_dealloc(struct bpf_link *link)
kfree(kmulti_link); kfree(kmulti_link);
} }
static int bpf_kprobe_multi_link_fill_link_info(const struct bpf_link *link,
struct bpf_link_info *info)
{
u64 __user *uaddrs = u64_to_user_ptr(info->kprobe_multi.addrs);
struct bpf_kprobe_multi_link *kmulti_link;
u32 ucount = info->kprobe_multi.count;
int err = 0, i;
if (!uaddrs ^ !ucount)
return -EINVAL;
kmulti_link = container_of(link, struct bpf_kprobe_multi_link, link);
info->kprobe_multi.count = kmulti_link->cnt;
info->kprobe_multi.flags = kmulti_link->flags;
if (!uaddrs)
return 0;
if (ucount < kmulti_link->cnt)
err = -ENOSPC;
else
ucount = kmulti_link->cnt;
if (kallsyms_show_value(current_cred())) {
if (copy_to_user(uaddrs, kmulti_link->addrs, ucount * sizeof(u64)))
return -EFAULT;
} else {
for (i = 0; i < ucount; i++) {
if (put_user(0, uaddrs + i))
return -EFAULT;
}
}
return err;
}
static const struct bpf_link_ops bpf_kprobe_multi_link_lops = { static const struct bpf_link_ops bpf_kprobe_multi_link_lops = {
.release = bpf_kprobe_multi_link_release, .release = bpf_kprobe_multi_link_release,
.dealloc = bpf_kprobe_multi_link_dealloc, .dealloc = bpf_kprobe_multi_link_dealloc,
.fill_link_info = bpf_kprobe_multi_link_fill_link_info,
}; };
static void bpf_kprobe_multi_cookie_swap(void *a, void *b, int size, const void *priv) static void bpf_kprobe_multi_cookie_swap(void *a, void *b, int size, const void *priv)
...@@ -2872,6 +2908,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr ...@@ -2872,6 +2908,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
link->addrs = addrs; link->addrs = addrs;
link->cookies = cookies; link->cookies = cookies;
link->cnt = cnt; link->cnt = cnt;
link->flags = flags;
if (cookies) { if (cookies) {
/* /*
......
...@@ -6439,6 +6439,11 @@ struct bpf_link_info { ...@@ -6439,6 +6439,11 @@ struct bpf_link_info {
__s32 priority; __s32 priority;
__u32 flags; __u32 flags;
} netfilter; } netfilter;
struct {
__aligned_u64 addrs;
__u32 count; /* in/out: kprobe_multi function count */
__u32 flags;
} kprobe_multi;
}; };
} __attribute__((aligned(8))); } __attribute__((aligned(8)));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment