| @@ -3003,6 +3003,7 @@ struct bpf_uprobe_multi_link { · 3002 unmodified lines |
| 3003 | 3003 | struct bpf_link link; |
| 3004 | 3004 | u32 cnt; |
| 3005 | 3005 | struct bpf_uprobe *uprobes; |
| 3006 | + struct task_struct *task; |
| 3006 | 3007 | }; |
| 3007 | 3008 | |
| 3008 | 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 | 3036 | struct bpf_uprobe_multi_link *umulti_link; |
| 3036 | 3037 | |
| 3037 | 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 | 3041 | path_put(&umulti_link->path); |
| 3039 | 3042 | kvfree(umulti_link->uprobes); |
| 3040 | 3043 | kfree(umulti_link); |
| @@ -3059,6 +3062,9 @@ static int uprobe_prog_run(struct bpf_uprobe *uprobe, · 18 unmodified lines |
| 3059 | 3062 | struct bpf_run_ctx *old_run_ctx; |
| 3060 | 3063 | int err = 0; |
| 3061 | 3064 | |
| 3065 | + if (link->task && current != link->task) |
| 3066 | + return 0; |
| 3067 | + |
| 3062 | 3068 | if (sleepable) |
| 3063 | 3069 | rcu_read_lock_trace(); |
| 3064 | 3070 | else |
| @@ -3079,6 +3085,16 @@ static int uprobe_prog_run(struct bpf_uprobe *uprobe, · 14 unmodified lines |
| 3079 | 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 | 3098 | static int |
| 3083 | 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 | 3128 | unsigned long *ref_ctr_offsets = NULL; |
| 3113 | 3129 | struct bpf_link_primer link_primer; |
| 3114 | 3130 | struct bpf_uprobe *uprobes = NULL; |
| 3131 | + struct task_struct *task = NULL; |
| 3115 | 3132 | unsigned long __user *uoffsets; |
| 3116 | 3133 | u64 __user *ucookies; |
| 3117 | 3134 | void __user *upath; |
| 3118 | 3135 | u32 flags, cnt, i; |
| 3119 | 3136 | struct path path; |
| 3120 | 3137 | char *name; |
| 3138 | + pid_t pid; |
| 3121 | 3139 | int err; |
| 3122 | 3140 | |
| 3123 | 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 | 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 | 3191 | err = -ENOMEM; |
| 3165 | 3192 | |
| 3166 | 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 | 3222 | uprobes[i].consumer.ret_handler = uprobe_multi_link_ret_handler; |
| 3196 | 3223 | else |
| 3197 | 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 | 3230 | link->cnt = cnt; |
| 3201 | 3231 | link->uprobes = uprobes; |
| 3202 | 3232 | link->path = path; |
| 3233 | + link->task = task; |
| 3203 | 3234 | |
| 3204 | 3235 | bpf_link_init(&link->link, BPF_LINK_TYPE_UPROBE_MULTI, |
| 3205 | 3236 | &bpf_uprobe_multi_link_lops, prog); |
| @@ -3226,6 +3257,8 @@ error_free: · 20 unmodified lines |
| 3226 | 3257 | kvfree(ref_ctr_offsets); |
| 3227 | 3258 | kvfree(uprobes); |
| 3228 | 3259 | kfree(link); |
| 3260 | + if (task) |
| 3261 | + put_task_struct(task); |
| 3229 | 3262 | error_path_put: |
| 3230 | 3263 | path_put(&path); |
| 3231 | 3264 | return err; |