History

bpf: Add link_info support for uprobe multi link

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.

Jiri Olsa committed 2 years ago

Commit e56fdbf1 parent 4930b7f3 files · +92 −0Browse files

Unified · Split

3 files
  1. include/uapi/linux/bpf.h +10 −0
  2. kernel/trace/bpf_trace.c +72 −0
  3. tools/include/uapi/linux/bpf.h +10 −0
include/uapi/linux/bpf.h+10−0
@@ -6562,6 +6562,16 @@ struct bpf_link_info { · 6561 unmodified lines
6562 __u32 flags;6562 __u32 flags;
6563 __u64 missed;6563 __u64 missed;
6564 } kprobe_multi;6564 } kprobe_multi;
6565 struct {
6566 __aligned_u64 path;
6567 __aligned_u64 offsets;
6568 __aligned_u64 ref_ctr_offsets;
6569 __aligned_u64 cookies;
6570 __u32 path_size; /* in/out: real path size on success, including zero byte */
6571 __u32 count; /* in/out: uprobe_multi offsets/ref_ctr_offsets/cookies count */
6572 __u32 flags;
6573 __u32 pid;
6574 } uprobe_multi;
6565 struct {6575 struct {
6566 __u32 type; /* enum bpf_perf_event_type */6576 __u32 type; /* enum bpf_perf_event_type */
6567 __u32 :32;6577 __u32 :32;
kernel/trace/bpf_trace.c+72−0
@@ -3042,6 +3042,7 @@ struct bpf_uprobe_multi_link { · 3041 unmodified lines
3042 struct path path;3042 struct path path;
3043 struct bpf_link link;3043 struct bpf_link link;
3044 u32 cnt;3044 u32 cnt;
3045 u32 flags;
3045 struct bpf_uprobe *uprobes;3046 struct bpf_uprobe *uprobes;
3046 struct task_struct *task;3047 struct task_struct *task;
3047};3048};
@@ -3083,9 +3084,79 @@ static void bpf_uprobe_multi_link_dealloc(struct bpf_link *link) · 35 unmodified lines
3083 kfree(umulti_link);3084 kfree(umulti_link);
3084}3085}
3085 3086
3087static int bpf_uprobe_multi_link_fill_link_info(const struct bpf_link *link,
3088 struct bpf_link_info *info)
3089{
3090 u64 __user *uref_ctr_offsets = u64_to_user_ptr(info->uprobe_multi.ref_ctr_offsets);
3091 u64 __user *ucookies = u64_to_user_ptr(info->uprobe_multi.cookies);
3092 u64 __user *uoffsets = u64_to_user_ptr(info->uprobe_multi.offsets);
3093 u64 __user *upath = u64_to_user_ptr(info->uprobe_multi.path);
3094 u32 upath_size = info->uprobe_multi.path_size;
3095 struct bpf_uprobe_multi_link *umulti_link;
3096 u32 ucount = info->uprobe_multi.count;
3097 int err = 0, i;
3098 long left;
3099
3100 if (!upath ^ !upath_size)
3101 return -EINVAL;
3102
3103 if ((uoffsets || uref_ctr_offsets || ucookies) && !ucount)
3104 return -EINVAL;
3105
3106 umulti_link = container_of(link, struct bpf_uprobe_multi_link, link);
3107 info->uprobe_multi.count = umulti_link->cnt;
3108 info->uprobe_multi.flags = umulti_link->flags;
3109 info->uprobe_multi.pid = umulti_link->task ?
3110 task_pid_nr_ns(umulti_link->task, task_active_pid_ns(current)) : 0;
3111
3112 if (upath) {
3113 char *p, *buf;
3114
3115 upath_size = min_t(u32, upath_size, PATH_MAX);
3116
3117 buf = kmalloc(upath_size, GFP_KERNEL);
3118 if (!buf)
3119 return -ENOMEM;
3120 p = d_path(&umulti_link->path, buf, upath_size);
3121 if (IS_ERR(p)) {
3122 kfree(buf);
3123 return PTR_ERR(p);
3124 }
3125 upath_size = buf + upath_size - p;
3126 left = copy_to_user(upath, p, upath_size);
3127 kfree(buf);
3128 if (left)
3129 return -EFAULT;
3130 info->uprobe_multi.path_size = upath_size;
3131 }
3132
3133 if (!uoffsets && !ucookies && !uref_ctr_offsets)
3134 return 0;
3135
3136 if (ucount < umulti_link->cnt)
3137 err = -ENOSPC;
3138 else
3139 ucount = umulti_link->cnt;
3140
3141 for (i = 0; i < ucount; i++) {
3142 if (uoffsets &&
3143 put_user(umulti_link->uprobes[i].offset, uoffsets + i))
3144 return -EFAULT;
3145 if (uref_ctr_offsets &&
3146 put_user(umulti_link->uprobes[i].ref_ctr_offset, uref_ctr_offsets + i))
3147 return -EFAULT;
3148 if (ucookies &&
3149 put_user(umulti_link->uprobes[i].cookie, ucookies + i))
3150 return -EFAULT;
3151 }
3152
3153 return err;
3154}
3155
3086static const struct bpf_link_ops bpf_uprobe_multi_link_lops = {3156static const struct bpf_link_ops bpf_uprobe_multi_link_lops = {
3087 .release = bpf_uprobe_multi_link_release,3157 .release = bpf_uprobe_multi_link_release,
3088 .dealloc = bpf_uprobe_multi_link_dealloc,3158 .dealloc = bpf_uprobe_multi_link_dealloc,
3159 .fill_link_info = bpf_uprobe_multi_link_fill_link_info,
3089};3160};
3090 3161
3091static int uprobe_prog_run(struct bpf_uprobe *uprobe,3162static int uprobe_prog_run(struct bpf_uprobe *uprobe,
@@ -3274,6 +3345,7 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr · 182 unmodified lines
3274 link->uprobes = uprobes;3345 link->uprobes = uprobes;
3275 link->path = path;3346 link->path = path;
3276 link->task = task;3347 link->task = task;
3348 link->flags = flags;
3277 3349
3278 bpf_link_init(&link->link, BPF_LINK_TYPE_UPROBE_MULTI,3350 bpf_link_init(&link->link, BPF_LINK_TYPE_UPROBE_MULTI,
3279 &bpf_uprobe_multi_link_lops, prog);3351 &bpf_uprobe_multi_link_lops, prog);
tools/include/uapi/linux/bpf.h+10−0
@@ -6562,6 +6562,16 @@ struct bpf_link_info { · 6561 unmodified lines
6562 __u32 flags;6562 __u32 flags;
6563 __u64 missed;6563 __u64 missed;
6564 } kprobe_multi;6564 } kprobe_multi;
6565 struct {
6566 __aligned_u64 path;
6567 __aligned_u64 offsets;
6568 __aligned_u64 ref_ctr_offsets;
6569 __aligned_u64 cookies;
6570 __u32 path_size; /* in/out: real path size on success, including zero byte */
6571 __u32 count; /* in/out: uprobe_multi offsets/ref_ctr_offsets/cookies count */
6572 __u32 flags;
6573 __u32 pid;
6574 } uprobe_multi;
6565 struct {6575 struct {
6566 __u32 type; /* enum bpf_perf_event_type */6576 __u32 type; /* enum bpf_perf_event_type */
6567 __u32 :32;6577 __u32 :32;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t