aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index b927da66f653..51bee695d32c 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1168,6 +1168,9 @@ static int sockmap_get_from_fd(const union bpf_attr *attr, bool attach)
1168 return 0; 1168 return 0;
1169} 1169}
1170 1170
1171#define BPF_F_ATTACH_MASK \
1172 (BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI)
1173
1171static int bpf_prog_attach(const union bpf_attr *attr) 1174static int bpf_prog_attach(const union bpf_attr *attr)
1172{ 1175{
1173 enum bpf_prog_type ptype; 1176 enum bpf_prog_type ptype;
@@ -1181,7 +1184,7 @@ static int bpf_prog_attach(const union bpf_attr *attr)
1181 if (CHECK_ATTR(BPF_PROG_ATTACH)) 1184 if (CHECK_ATTR(BPF_PROG_ATTACH))
1182 return -EINVAL; 1185 return -EINVAL;
1183 1186
1184 if (attr->attach_flags & ~BPF_F_ALLOW_OVERRIDE) 1187 if (attr->attach_flags & ~BPF_F_ATTACH_MASK)
1185 return -EINVAL; 1188 return -EINVAL;
1186 1189
1187 switch (attr->attach_type) { 1190 switch (attr->attach_type) {
@@ -1212,8 +1215,8 @@ static int bpf_prog_attach(const union bpf_attr *attr)
1212 return PTR_ERR(cgrp); 1215 return PTR_ERR(cgrp);
1213 } 1216 }
1214 1217
1215 ret = cgroup_bpf_update(cgrp, prog, attr->attach_type, 1218 ret = cgroup_bpf_attach(cgrp, prog, attr->attach_type,
1216 attr->attach_flags & BPF_F_ALLOW_OVERRIDE); 1219 attr->attach_flags);
1217 if (ret) 1220 if (ret)
1218 bpf_prog_put(prog); 1221 bpf_prog_put(prog);
1219 cgroup_put(cgrp); 1222 cgroup_put(cgrp);
@@ -1225,6 +1228,8 @@ static int bpf_prog_attach(const union bpf_attr *attr)
1225 1228
1226static int bpf_prog_detach(const union bpf_attr *attr) 1229static int bpf_prog_detach(const union bpf_attr *attr)
1227{ 1230{
1231 enum bpf_prog_type ptype;
1232 struct bpf_prog *prog;
1228 struct cgroup *cgrp; 1233 struct cgroup *cgrp;
1229 int ret; 1234 int ret;
1230 1235
@@ -1237,23 +1242,33 @@ static int bpf_prog_detach(const union bpf_attr *attr)
1237 switch (attr->attach_type) { 1242 switch (attr->attach_type) {
1238 case BPF_CGROUP_INET_INGRESS: 1243 case BPF_CGROUP_INET_INGRESS:
1239 case BPF_CGROUP_INET_EGRESS: 1244 case BPF_CGROUP_INET_EGRESS:
1245 ptype = BPF_PROG_TYPE_CGROUP_SKB;
1246 break;
1240 case BPF_CGROUP_INET_SOCK_CREATE: 1247 case BPF_CGROUP_INET_SOCK_CREATE:
1248 ptype = BPF_PROG_TYPE_CGROUP_SOCK;
1249 break;
1241 case BPF_CGROUP_SOCK_OPS: 1250 case BPF_CGROUP_SOCK_OPS:
1242 cgrp = cgroup_get_from_fd(attr->target_fd); 1251 ptype = BPF_PROG_TYPE_SOCK_OPS;
1243 if (IS_ERR(cgrp))
1244 return PTR_ERR(cgrp);
1245
1246 ret = cgroup_bpf_update(cgrp, NULL, attr->attach_type, false);
1247 cgroup_put(cgrp);
1248 break; 1252 break;
1249 case BPF_SK_SKB_STREAM_PARSER: 1253 case BPF_SK_SKB_STREAM_PARSER:
1250 case BPF_SK_SKB_STREAM_VERDICT: 1254 case BPF_SK_SKB_STREAM_VERDICT:
1251 ret = sockmap_get_from_fd(attr, false); 1255 return sockmap_get_from_fd(attr, false);
1252 break;
1253 default: 1256 default:
1254 return -EINVAL; 1257 return -EINVAL;
1255 } 1258 }
1256 1259
1260 cgrp = cgroup_get_from_fd(attr->target_fd);
1261 if (IS_ERR(cgrp))
1262 return PTR_ERR(cgrp);
1263
1264 prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype);
1265 if (IS_ERR(prog))
1266 prog = NULL;
1267
1268 ret = cgroup_bpf_detach(cgrp, prog, attr->attach_type, 0);
1269 if (prog)
1270 bpf_prog_put(prog);
1271 cgroup_put(cgrp);
1257 return ret; 1272 return ret;
1258} 1273}
1259 1274