diff options
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r-- | kernel/bpf/syscall.c | 37 |
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 | |||
1171 | static int bpf_prog_attach(const union bpf_attr *attr) | 1174 | static 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 | ||
1226 | static int bpf_prog_detach(const union bpf_attr *attr) | 1229 | static 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 | ||