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;
|
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
|
static enum bpf_prog_type
|
||||||
attach_type_to_prog_type(enum bpf_attach_type attach_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_PROG_ATTACH_LAST_FIELD expected_revision
|
||||||
|
|
||||||
#define BPF_F_ATTACH_MASK_BASE \
|
#define BPF_F_ATTACH_MASK_BASE \
|
||||||
@ -4855,7 +4879,6 @@ err_put:
|
|||||||
#define BPF_LINK_CREATE_LAST_FIELD link_create.kprobe_multi.cookies
|
#define BPF_LINK_CREATE_LAST_FIELD link_create.kprobe_multi.cookies
|
||||||
static int link_create(union bpf_attr *attr, bpfptr_t uattr)
|
static int link_create(union bpf_attr *attr, bpfptr_t uattr)
|
||||||
{
|
{
|
||||||
enum bpf_prog_type ptype;
|
|
||||||
struct bpf_prog *prog;
|
struct bpf_prog *prog;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -4874,45 +4897,6 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
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) {
|
switch (prog->type) {
|
||||||
case BPF_PROG_TYPE_CGROUP_SKB:
|
case BPF_PROG_TYPE_CGROUP_SKB:
|
||||||
case BPF_PROG_TYPE_CGROUP_SOCK:
|
case BPF_PROG_TYPE_CGROUP_SOCK:
|
||||||
|
Loading…
Reference in New Issue
Block a user