| @@ -3003,6 +3003,7 @@ struct bpf_uprobe_multi_link { · 3002 unmodified lines |
| 3003 | struct bpf_link link; | 3003 | struct bpf_link link; |
| 3004 | u32 cnt; | 3004 | u32 cnt; |
| 3005 | struct bpf_uprobe *uprobes; | 3005 | struct bpf_uprobe *uprobes; |
| | 3006 | struct task_struct *task; |
| 3006 | }; | 3007 | }; |
| 3007 | | 3008 | |
| 3008 | struct bpf_uprobe_multi_run_ctx { | 3009 | struct bpf_uprobe_multi_run_ctx { |
| @@ -3035,6 +3036,8 @@ static void bpf_uprobe_multi_link_dealloc(struct bpf_link *link) · 26 unmodified lines |
| 3035 | struct bpf_uprobe_multi_link *umulti_link; | 3036 | struct bpf_uprobe_multi_link *umulti_link; |
| 3036 | | 3037 | |
| 3037 | umulti_link = container_of(link, struct bpf_uprobe_multi_link, link); | 3038 | umulti_link = container_of(link, struct bpf_uprobe_multi_link, link); |
| | 3039 | if (umulti_link->task) |
| | 3040 | put_task_struct(umulti_link->task); |
| 3038 | path_put(&umulti_link->path); | 3041 | path_put(&umulti_link->path); |
| 3039 | kvfree(umulti_link->uprobes); | 3042 | kvfree(umulti_link->uprobes); |
| 3040 | kfree(umulti_link); | 3043 | kfree(umulti_link); |
| @@ -3059,6 +3062,9 @@ static int uprobe_prog_run(struct bpf_uprobe *uprobe, · 18 unmodified lines |
| 3059 | struct bpf_run_ctx *old_run_ctx; | 3062 | struct bpf_run_ctx *old_run_ctx; |
| 3060 | int err = 0; | 3063 | int err = 0; |
| 3061 | | 3064 | |
| | 3065 | if (link->task && current != link->task) |
| | 3066 | return 0; |
| | 3067 | |
| 3062 | if (sleepable) | 3068 | if (sleepable) |
| 3063 | rcu_read_lock_trace(); | 3069 | rcu_read_lock_trace(); |
| 3064 | else | 3070 | else |
| @@ -3079,6 +3085,16 @@ static int uprobe_prog_run(struct bpf_uprobe *uprobe, · 14 unmodified lines |
| 3079 | return err; | 3085 | return err; |
| 3080 | } | 3086 | } |
| 3081 | | 3087 | |
| | 3088 | static bool |
| | 3089 | uprobe_multi_link_filter(struct uprobe_consumer *con, enum uprobe_filter_ctx ctx, |
| | 3090 | struct mm_struct *mm) |
| | 3091 | { |
| | 3092 | struct bpf_uprobe *uprobe; |
| | 3093 | |
| | 3094 | uprobe = container_of(con, struct bpf_uprobe, consumer); |
| | 3095 | return uprobe->link->task->mm == mm; |
| | 3096 | } |
| | 3097 | |
| 3082 | static int | 3098 | static int |
| 3083 | uprobe_multi_link_handler(struct uprobe_consumer *con, struct pt_regs *regs) | 3099 | uprobe_multi_link_handler(struct uprobe_consumer *con, struct pt_regs *regs) |
| 3084 | { | 3100 | { |
| @@ -3112,12 +3128,14 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr · 27 unmodified lines |
| 3112 | unsigned long *ref_ctr_offsets = NULL; | 3128 | unsigned long *ref_ctr_offsets = NULL; |
| 3113 | struct bpf_link_primer link_primer; | 3129 | struct bpf_link_primer link_primer; |
| 3114 | struct bpf_uprobe *uprobes = NULL; | 3130 | struct bpf_uprobe *uprobes = NULL; |
| | 3131 | struct task_struct *task = NULL; |
| 3115 | unsigned long __user *uoffsets; | 3132 | unsigned long __user *uoffsets; |
| 3116 | u64 __user *ucookies; | 3133 | u64 __user *ucookies; |
| 3117 | void __user *upath; | 3134 | void __user *upath; |
| 3118 | u32 flags, cnt, i; | 3135 | u32 flags, cnt, i; |
| 3119 | struct path path; | 3136 | struct path path; |
| 3120 | char *name; | 3137 | char *name; |
| | 3138 | pid_t pid; |
| 3121 | int err; | 3139 | int err; |
| 3122 | | 3140 | |
| 3123 | /* no support for 32bit archs yet */ | 3141 | /* no support for 32bit archs yet */ |
| @@ -3161,6 +3179,15 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr · 37 unmodified lines |
| 3161 | goto error_path_put; | 3179 | goto error_path_put; |
| 3162 | } | 3180 | } |
| 3163 | | 3181 | |
| | 3182 | pid = attr->link_create.uprobe_multi.pid; |
| | 3183 | if (pid) { |
| | 3184 | rcu_read_lock(); |
| | 3185 | task = get_pid_task(find_vpid(pid), PIDTYPE_PID); |
| | 3186 | rcu_read_unlock(); |
| | 3187 | if (!task) |
| | 3188 | goto error_path_put; |
| | 3189 | } |
| | 3190 | |
| 3164 | err = -ENOMEM; | 3191 | err = -ENOMEM; |
| 3165 | | 3192 | |
| 3166 | link = kzalloc(sizeof(*link), GFP_KERNEL); | 3193 | link = kzalloc(sizeof(*link), GFP_KERNEL); |
| @@ -3195,11 +3222,15 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr · 28 unmodified lines |
| 3195 | uprobes[i].consumer.ret_handler = uprobe_multi_link_ret_handler; | 3222 | uprobes[i].consumer.ret_handler = uprobe_multi_link_ret_handler; |
| 3196 | else | 3223 | else |
| 3197 | uprobes[i].consumer.handler = uprobe_multi_link_handler; | 3224 | uprobes[i].consumer.handler = uprobe_multi_link_handler; |
| | 3225 | |
| | 3226 | if (pid) |
| | 3227 | uprobes[i].consumer.filter = uprobe_multi_link_filter; |
| 3198 | } | 3228 | } |
| 3199 | | 3229 | |
| 3200 | link->cnt = cnt; | 3230 | link->cnt = cnt; |
| 3201 | link->uprobes = uprobes; | 3231 | link->uprobes = uprobes; |
| 3202 | link->path = path; | 3232 | link->path = path; |
| | 3233 | link->task = task; |
| 3203 | | 3234 | |
| 3204 | bpf_link_init(&link->link, BPF_LINK_TYPE_UPROBE_MULTI, | 3235 | bpf_link_init(&link->link, BPF_LINK_TYPE_UPROBE_MULTI, |
| 3205 | &bpf_uprobe_multi_link_lops, prog); | 3236 | &bpf_uprobe_multi_link_lops, prog); |
| @@ -3226,6 +3257,8 @@ error_free: · 20 unmodified lines |
| 3226 | kvfree(ref_ctr_offsets); | 3257 | kvfree(ref_ctr_offsets); |
| 3227 | kvfree(uprobes); | 3258 | kvfree(uprobes); |
| 3228 | kfree(link); | 3259 | kfree(link); |
| | 3260 | if (task) |
| | 3261 | put_task_struct(task); |
| 3229 | error_path_put: | 3262 | error_path_put: |
| 3230 | path_put(&path); | 3263 | path_put(&path); |
| 3231 | return err; | 3264 | return err; |