bpf: Support ->fill_link_info for kprobe_multi
authorYafang Shao <laoar.shao@gmail.com>
Sun, 9 Jul 2023 02:56:21 +0000 (02:56 +0000)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 12 Jul 2023 03:07:50 +0000 (20:07 -0700)
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: Yafang Shao <laoar.shao@gmail.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20230709025630.3735-2-laoar.shao@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/uapi/linux/bpf.h
kernel/trace/bpf_trace.c
tools/include/uapi/linux/bpf.h

index 60a9d59beeabba9bdbaa94946aa0c28e3f435463..a4e881c64e0fe5f2f12d19b9d8f5c7de1c0965e3 100644 (file)
@@ -6439,6 +6439,11 @@ struct bpf_link_info {
                        __s32 priority;
                        __u32 flags;
                } netfilter;
+               struct {
+                       __aligned_u64 addrs;
+                       __u32 count; /* in/out: kprobe_multi function count */
+                       __u32 flags;
+               } kprobe_multi;
        };
 } __attribute__((aligned(8)));
 
index 03b7f6b8e4f0c272a780ed37a3a0cd179d82b635..acb3d6dd7a772edde9ba1df82f9057b744285361 100644 (file)
@@ -2469,6 +2469,7 @@ struct bpf_kprobe_multi_link {
        u32 cnt;
        u32 mods_cnt;
        struct module **mods;
+       u32 flags;
 };
 
 struct bpf_kprobe_multi_run_ctx {
@@ -2558,9 +2559,44 @@ static void bpf_kprobe_multi_link_dealloc(struct bpf_link *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 = {
        .release = bpf_kprobe_multi_link_release,
        .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)
@@ -2872,6 +2908,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
        link->addrs = addrs;
        link->cookies = cookies;
        link->cnt = cnt;
+       link->flags = flags;
 
        if (cookies) {
                /*
index 60a9d59beeabba9bdbaa94946aa0c28e3f435463..a4e881c64e0fe5f2f12d19b9d8f5c7de1c0965e3 100644 (file)
@@ -6439,6 +6439,11 @@ struct bpf_link_info {
                        __s32 priority;
                        __u32 flags;
                } netfilter;
+               struct {
+                       __aligned_u64 addrs;
+                       __u32 count; /* in/out: kprobe_multi function count */
+                       __u32 flags;
+               } kprobe_multi;
        };
 } __attribute__((aligned(8)));