diff options
Diffstat (limited to 'kernel/bpf/syscall.c')
| -rw-r--r-- | kernel/bpf/syscall.c | 45 | 
1 files changed, 32 insertions, 13 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index a8f1808a1ca5..c5aa127ed4cc 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -3069,13 +3069,17 @@ static void bpf_link_show_fdinfo(struct seq_file *m, struct file *filp)  {  	const struct bpf_link *link = filp->private_data;  	const struct bpf_prog *prog = link->prog; +	enum bpf_link_type type = link->type;  	char prog_tag[sizeof(prog->tag) * 2 + 1] = { }; -	seq_printf(m, -		   "link_type:\t%s\n" -		   "link_id:\t%u\n", -		   bpf_link_type_strs[link->type], -		   link->id); +	if (type < ARRAY_SIZE(bpf_link_type_strs) && bpf_link_type_strs[type]) { +		seq_printf(m, "link_type:\t%s\n", bpf_link_type_strs[type]); +	} else { +		WARN_ONCE(1, "missing BPF_LINK_TYPE(...) for link type %u\n", type); +		seq_printf(m, "link_type:\t<%u>\n", type); +	} +	seq_printf(m, "link_id:\t%u\n", link->id); +  	if (prog) {  		bin2hex(prog_tag, prog->tag, sizeof(prog->tag));  		seq_printf(m, @@ -3565,15 +3569,16 @@ static void bpf_perf_link_dealloc(struct bpf_link *link)  }  static int bpf_perf_link_fill_common(const struct perf_event *event, -				     char __user *uname, u32 ulen, +				     char __user *uname, u32 *ulenp,  				     u64 *probe_offset, u64 *probe_addr,  				     u32 *fd_type, unsigned long *missed)  {  	const char *buf; -	u32 prog_id; +	u32 prog_id, ulen;  	size_t len;  	int err; +	ulen = *ulenp;  	if (!ulen ^ !uname)  		return -EINVAL; @@ -3581,10 +3586,17 @@ static int bpf_perf_link_fill_common(const struct perf_event *event,  				      probe_offset, probe_addr, missed);  	if (err)  		return err; + +	if (buf) { +		len = strlen(buf); +		*ulenp = len + 1; +	} else { +		*ulenp = 1; +	}  	if (!uname)  		return 0; +  	if (buf) { -		len = strlen(buf);  		err = bpf_copy_to_user(uname, buf, ulen, len);  		if (err)  			return err; @@ -3609,7 +3621,7 @@ static int bpf_perf_link_fill_kprobe(const struct perf_event *event,  	uname = u64_to_user_ptr(info->perf_event.kprobe.func_name);  	ulen = info->perf_event.kprobe.name_len; -	err = bpf_perf_link_fill_common(event, uname, ulen, &offset, &addr, +	err = bpf_perf_link_fill_common(event, uname, &ulen, &offset, &addr,  					&type, &missed);  	if (err)  		return err; @@ -3617,7 +3629,7 @@ static int bpf_perf_link_fill_kprobe(const struct perf_event *event,  		info->perf_event.type = BPF_PERF_EVENT_KRETPROBE;  	else  		info->perf_event.type = BPF_PERF_EVENT_KPROBE; - +	info->perf_event.kprobe.name_len = ulen;  	info->perf_event.kprobe.offset = offset;  	info->perf_event.kprobe.missed = missed;  	if (!kallsyms_show_value(current_cred())) @@ -3639,7 +3651,7 @@ static int bpf_perf_link_fill_uprobe(const struct perf_event *event,  	uname = u64_to_user_ptr(info->perf_event.uprobe.file_name);  	ulen = info->perf_event.uprobe.name_len; -	err = bpf_perf_link_fill_common(event, uname, ulen, &offset, &addr, +	err = bpf_perf_link_fill_common(event, uname, &ulen, &offset, &addr,  					&type, NULL);  	if (err)  		return err; @@ -3648,6 +3660,7 @@ static int bpf_perf_link_fill_uprobe(const struct perf_event *event,  		info->perf_event.type = BPF_PERF_EVENT_URETPROBE;  	else  		info->perf_event.type = BPF_PERF_EVENT_UPROBE; +	info->perf_event.uprobe.name_len = ulen;  	info->perf_event.uprobe.offset = offset;  	info->perf_event.uprobe.cookie = event->bpf_cookie;  	return 0; @@ -3673,12 +3686,18 @@ static int bpf_perf_link_fill_tracepoint(const struct perf_event *event,  {  	char __user *uname;  	u32 ulen; +	int err;  	uname = u64_to_user_ptr(info->perf_event.tracepoint.tp_name);  	ulen = info->perf_event.tracepoint.name_len; +	err = bpf_perf_link_fill_common(event, uname, &ulen, NULL, NULL, NULL, NULL); +	if (err) +		return err; +  	info->perf_event.type = BPF_PERF_EVENT_TRACEPOINT; +	info->perf_event.tracepoint.name_len = ulen;  	info->perf_event.tracepoint.cookie = event->bpf_cookie; -	return bpf_perf_link_fill_common(event, uname, ulen, NULL, NULL, NULL, NULL); +	return 0;  }  static int bpf_perf_link_fill_perf_event(const struct perf_event *event, @@ -5877,7 +5896,7 @@ static const struct bpf_func_proto bpf_kallsyms_lookup_name_proto = {  	.arg1_type	= ARG_PTR_TO_MEM,  	.arg2_type	= ARG_CONST_SIZE_OR_ZERO,  	.arg3_type	= ARG_ANYTHING, -	.arg4_type	= ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED, +	.arg4_type	= ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_WRITE | MEM_ALIGNED,  	.arg4_size	= sizeof(u64),  };  | 
