bpf: Add attach_type checks under bpf_prog_attach_check_attach_type
Add extra attach_type checks from link_create under bpf_prog_attach_check_attach_type. Suggested-by: Andrii Nakryiko <andrii@kernel.org> Acked-by: Andrii Nakryiko <andrii@kernel.org> Acked-by: Yafang Shao <laoar.shao@gmail.com> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Acked-by: Yonghong Song <yonghong.song@linux.dev> Link: https://lore.kernel.org/r/20230809083440.3209381-3-jolsa@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
c5487f8d91
commit
3505cb9fa2
@ -3655,34 +3655,6 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
|
||||
enum bpf_attach_type attach_type)
|
||||
{
|
||||
switch (prog->type) {
|
||||
case BPF_PROG_TYPE_CGROUP_SOCK:
|
||||
case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
|
||||
case BPF_PROG_TYPE_CGROUP_SOCKOPT:
|
||||
case BPF_PROG_TYPE_SK_LOOKUP:
|
||||
return attach_type == prog->expected_attach_type ? 0 : -EINVAL;
|
||||
case BPF_PROG_TYPE_CGROUP_SKB:
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
/* cg-skb progs can be loaded by unpriv user.
|
||||
* check permissions at attach time.
|
||||
*/
|
||||
return -EPERM;
|
||||
return prog->enforce_expected_attach_type &&
|
||||
prog->expected_attach_type != attach_type ?
|
||||
-EINVAL : 0;
|
||||
case BPF_PROG_TYPE_KPROBE:
|
||||
if (prog->expected_attach_type == BPF_TRACE_KPROBE_MULTI &&
|
||||
attach_type != BPF_TRACE_KPROBE_MULTI)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static enum bpf_prog_type
|
||||
attach_type_to_prog_type(enum bpf_attach_type attach_type)
|
||||
{
|
||||
@ -3749,6 +3721,58 @@ attach_type_to_prog_type(enum bpf_attach_type attach_type)
|
||||
}
|
||||
}
|
||||
|
||||
static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
|
||||
enum bpf_attach_type attach_type)
|
||||
{
|
||||
enum bpf_prog_type ptype;
|
||||
|
||||
switch (prog->type) {
|
||||
case BPF_PROG_TYPE_CGROUP_SOCK:
|
||||
case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
|
||||
case BPF_PROG_TYPE_CGROUP_SOCKOPT:
|
||||
case BPF_PROG_TYPE_SK_LOOKUP:
|
||||
return attach_type == prog->expected_attach_type ? 0 : -EINVAL;
|
||||
case BPF_PROG_TYPE_CGROUP_SKB:
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
/* cg-skb progs can be loaded by unpriv user.
|
||||
* check permissions at attach time.
|
||||
*/
|
||||
return -EPERM;
|
||||
return prog->enforce_expected_attach_type &&
|
||||
prog->expected_attach_type != attach_type ?
|
||||
-EINVAL : 0;
|
||||
case BPF_PROG_TYPE_EXT:
|
||||
return 0;
|
||||
case BPF_PROG_TYPE_NETFILTER:
|
||||
if (attach_type != BPF_NETFILTER)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
case BPF_PROG_TYPE_PERF_EVENT:
|
||||
case BPF_PROG_TYPE_TRACEPOINT:
|
||||
if (attach_type != BPF_PERF_EVENT)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
case BPF_PROG_TYPE_KPROBE:
|
||||
if (prog->expected_attach_type == BPF_TRACE_KPROBE_MULTI &&
|
||||
attach_type != BPF_TRACE_KPROBE_MULTI)
|
||||
return -EINVAL;
|
||||
if (attach_type != BPF_PERF_EVENT &&
|
||||
attach_type != BPF_TRACE_KPROBE_MULTI)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
case BPF_PROG_TYPE_SCHED_CLS:
|
||||
if (attach_type != BPF_TCX_INGRESS &&
|
||||
attach_type != BPF_TCX_EGRESS)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
default:
|
||||
ptype = attach_type_to_prog_type(attach_type);
|
||||
if (ptype == BPF_PROG_TYPE_UNSPEC || ptype != prog->type)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define BPF_PROG_ATTACH_LAST_FIELD expected_revision
|
||||
|
||||
#define BPF_F_ATTACH_MASK_BASE \
|
||||
@ -4855,7 +4879,6 @@ err_put:
|
||||
#define BPF_LINK_CREATE_LAST_FIELD link_create.kprobe_multi.cookies
|
||||
static int link_create(union bpf_attr *attr, bpfptr_t uattr)
|
||||
{
|
||||
enum bpf_prog_type ptype;
|
||||
struct bpf_prog *prog;
|
||||
int ret;
|
||||
|
||||
@ -4874,45 +4897,6 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
switch (prog->type) {
|
||||
case BPF_PROG_TYPE_EXT:
|
||||
break;
|
||||
case BPF_PROG_TYPE_NETFILTER:
|
||||
if (attr->link_create.attach_type != BPF_NETFILTER) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case BPF_PROG_TYPE_PERF_EVENT:
|
||||
case BPF_PROG_TYPE_TRACEPOINT:
|
||||
if (attr->link_create.attach_type != BPF_PERF_EVENT) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case BPF_PROG_TYPE_KPROBE:
|
||||
if (attr->link_create.attach_type != BPF_PERF_EVENT &&
|
||||
attr->link_create.attach_type != BPF_TRACE_KPROBE_MULTI) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case BPF_PROG_TYPE_SCHED_CLS:
|
||||
if (attr->link_create.attach_type != BPF_TCX_INGRESS &&
|
||||
attr->link_create.attach_type != BPF_TCX_EGRESS) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ptype = attach_type_to_prog_type(attr->link_create.attach_type);
|
||||
if (ptype == BPF_PROG_TYPE_UNSPEC || ptype != prog->type) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (prog->type) {
|
||||
case BPF_PROG_TYPE_CGROUP_SKB:
|
||||
case BPF_PROG_TYPE_CGROUP_SOCK:
|
||||
|
Loading…
Reference in New Issue
Block a user