aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@fb.com>2017-02-10 23:28:24 -0500
committerDavid S. Miller <davem@davemloft.net>2017-02-12 21:52:19 -0500
commit7f677633379b4abb3281cdbe7e7006f049305c03 (patch)
tree1e5e662e792467d09f8a4ebf5b96b2baa333ae25 /kernel/bpf/syscall.c
parente722af6391949e8851310441bb0cec157d25611d (diff)
bpf: introduce BPF_F_ALLOW_OVERRIDE flag
If BPF_F_ALLOW_OVERRIDE flag is used in BPF_PROG_ATTACH command to the given cgroup the descendent cgroup will be able to override effective bpf program that was inherited from this cgroup. By default it's not passed, therefore override is disallowed. Examples: 1. prog X attached to /A with default prog Y fails to attach to /A/B and /A/B/C Everything under /A runs prog X 2. prog X attached to /A with allow_override. prog Y fails to attach to /A/B with default (non-override) prog M attached to /A/B with allow_override. Everything under /A/B runs prog M only. 3. prog X attached to /A with allow_override. prog Y fails to attach to /A with default. The user has to detach first to switch the mode. In the future this behavior may be extended with a chain of non-overridable programs. Also fix the bug where detach from cgroup where nothing is attached was not throwing error. Return ENOENT in such case. Add several testcases and adjust libbpf. Fixes: 3007098494be ("cgroup: add support for eBPF programs") Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Tejun Heo <tj@kernel.org> Acked-by: Daniel Mack <daniel@zonque.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 19b6129eab23..bbb016adbaeb 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -920,13 +920,14 @@ static int bpf_obj_get(const union bpf_attr *attr)
920 920
921#ifdef CONFIG_CGROUP_BPF 921#ifdef CONFIG_CGROUP_BPF
922 922
923#define BPF_PROG_ATTACH_LAST_FIELD attach_type 923#define BPF_PROG_ATTACH_LAST_FIELD attach_flags
924 924
925static int bpf_prog_attach(const union bpf_attr *attr) 925static int bpf_prog_attach(const union bpf_attr *attr)
926{ 926{
927 enum bpf_prog_type ptype;
927 struct bpf_prog *prog; 928 struct bpf_prog *prog;
928 struct cgroup *cgrp; 929 struct cgroup *cgrp;
929 enum bpf_prog_type ptype; 930 int ret;
930 931
931 if (!capable(CAP_NET_ADMIN)) 932 if (!capable(CAP_NET_ADMIN))
932 return -EPERM; 933 return -EPERM;
@@ -934,6 +935,9 @@ static int bpf_prog_attach(const union bpf_attr *attr)
934 if (CHECK_ATTR(BPF_PROG_ATTACH)) 935 if (CHECK_ATTR(BPF_PROG_ATTACH))
935 return -EINVAL; 936 return -EINVAL;
936 937
938 if (attr->attach_flags & ~BPF_F_ALLOW_OVERRIDE)
939 return -EINVAL;
940
937 switch (attr->attach_type) { 941 switch (attr->attach_type) {
938 case BPF_CGROUP_INET_INGRESS: 942 case BPF_CGROUP_INET_INGRESS:
939 case BPF_CGROUP_INET_EGRESS: 943 case BPF_CGROUP_INET_EGRESS:
@@ -956,10 +960,13 @@ static int bpf_prog_attach(const union bpf_attr *attr)
956 return PTR_ERR(cgrp); 960 return PTR_ERR(cgrp);
957 } 961 }
958 962
959 cgroup_bpf_update(cgrp, prog, attr->attach_type); 963 ret = cgroup_bpf_update(cgrp, prog, attr->attach_type,
964 attr->attach_flags & BPF_F_ALLOW_OVERRIDE);
965 if (ret)
966 bpf_prog_put(prog);
960 cgroup_put(cgrp); 967 cgroup_put(cgrp);
961 968
962 return 0; 969 return ret;
963} 970}
964 971
965#define BPF_PROG_DETACH_LAST_FIELD attach_type 972#define BPF_PROG_DETACH_LAST_FIELD attach_type
@@ -967,6 +974,7 @@ static int bpf_prog_attach(const union bpf_attr *attr)
967static int bpf_prog_detach(const union bpf_attr *attr) 974static int bpf_prog_detach(const union bpf_attr *attr)
968{ 975{
969 struct cgroup *cgrp; 976 struct cgroup *cgrp;
977 int ret;
970 978
971 if (!capable(CAP_NET_ADMIN)) 979 if (!capable(CAP_NET_ADMIN))
972 return -EPERM; 980 return -EPERM;
@@ -982,7 +990,7 @@ static int bpf_prog_detach(const union bpf_attr *attr)
982 if (IS_ERR(cgrp)) 990 if (IS_ERR(cgrp))
983 return PTR_ERR(cgrp); 991 return PTR_ERR(cgrp);
984 992
985 cgroup_bpf_update(cgrp, NULL, attr->attach_type); 993 ret = cgroup_bpf_update(cgrp, NULL, attr->attach_type, false);
986 cgroup_put(cgrp); 994 cgroup_put(cgrp);
987 break; 995 break;
988 996
@@ -990,7 +998,7 @@ static int bpf_prog_detach(const union bpf_attr *attr)
990 return -EINVAL; 998 return -EINVAL;
991 } 999 }
992 1000
993 return 0; 1001 return ret;
994} 1002}
995#endif /* CONFIG_CGROUP_BPF */ 1003#endif /* CONFIG_CGROUP_BPF */
996 1004