diff options
Diffstat (limited to 'tools/lib/bpf/bpf.c')
| -rw-r--r-- | tools/lib/bpf/bpf.c | 32 | 
1 files changed, 25 insertions, 7 deletions
| diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index 86dcac44f32f..2401fad090c5 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -684,8 +684,13 @@ int bpf_link_create(int prog_fd, int target_fd,  	iter_info_len = OPTS_GET(opts, iter_info_len, 0);  	target_btf_id = OPTS_GET(opts, target_btf_id, 0); -	if (iter_info_len && target_btf_id) -		return libbpf_err(-EINVAL); +	/* validate we don't have unexpected combinations of non-zero fields */ +	if (iter_info_len || target_btf_id) { +		if (iter_info_len && target_btf_id) +			return libbpf_err(-EINVAL); +		if (!OPTS_ZEROED(opts, target_btf_id)) +			return libbpf_err(-EINVAL); +	}  	memset(&attr, 0, sizeof(attr));  	attr.link_create.prog_fd = prog_fd; @@ -693,14 +698,27 @@ int bpf_link_create(int prog_fd, int target_fd,  	attr.link_create.attach_type = attach_type;  	attr.link_create.flags = OPTS_GET(opts, flags, 0); -	if (iter_info_len) { -		attr.link_create.iter_info = -			ptr_to_u64(OPTS_GET(opts, iter_info, (void *)0)); -		attr.link_create.iter_info_len = iter_info_len; -	} else if (target_btf_id) { +	if (target_btf_id) {  		attr.link_create.target_btf_id = target_btf_id; +		goto proceed;  	} +	switch (attach_type) { +	case BPF_TRACE_ITER: +		attr.link_create.iter_info = ptr_to_u64(OPTS_GET(opts, iter_info, (void *)0)); +		attr.link_create.iter_info_len = iter_info_len; +		break; +	case BPF_PERF_EVENT: +		attr.link_create.perf_event.bpf_cookie = OPTS_GET(opts, perf_event.bpf_cookie, 0); +		if (!OPTS_ZEROED(opts, perf_event)) +			return libbpf_err(-EINVAL); +		break; +	default: +		if (!OPTS_ZEROED(opts, flags)) +			return libbpf_err(-EINVAL); +		break; +	} +proceed:  	fd = sys_bpf(BPF_LINK_CREATE, &attr, sizeof(attr));  	return libbpf_err_errno(fd);  } | 
