aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf')
-rw-r--r--kernel/bpf/cgroup.c3
-rw-r--r--kernel/bpf/syscall.c31
-rw-r--r--kernel/bpf/verifier.c6
3 files changed, 35 insertions, 5 deletions
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index c1c0b60d3f2f..8730b24ed540 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -545,7 +545,7 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
545EXPORT_SYMBOL(__cgroup_bpf_check_dev_permission); 545EXPORT_SYMBOL(__cgroup_bpf_check_dev_permission);
546 546
547static const struct bpf_func_proto * 547static const struct bpf_func_proto *
548cgroup_dev_func_proto(enum bpf_func_id func_id) 548cgroup_dev_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
549{ 549{
550 switch (func_id) { 550 switch (func_id) {
551 case BPF_FUNC_map_lookup_elem: 551 case BPF_FUNC_map_lookup_elem:
@@ -566,6 +566,7 @@ cgroup_dev_func_proto(enum bpf_func_id func_id)
566 566
567static bool cgroup_dev_is_valid_access(int off, int size, 567static bool cgroup_dev_is_valid_access(int off, int size,
568 enum bpf_access_type type, 568 enum bpf_access_type type,
569 const struct bpf_prog *prog,
569 struct bpf_insn_access_aux *info) 570 struct bpf_insn_access_aux *info)
570{ 571{
571 const int size_default = sizeof(__u32); 572 const int size_default = sizeof(__u32);
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 95ca2523fa6e..9d3b572d4dec 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1171,8 +1171,27 @@ struct bpf_prog *bpf_prog_get_type_dev(u32 ufd, enum bpf_prog_type type,
1171} 1171}
1172EXPORT_SYMBOL_GPL(bpf_prog_get_type_dev); 1172EXPORT_SYMBOL_GPL(bpf_prog_get_type_dev);
1173 1173
1174static int
1175bpf_prog_load_check_attach_type(enum bpf_prog_type prog_type,
1176 enum bpf_attach_type expected_attach_type)
1177{
1178 /* There are currently no prog types that require specifying
1179 * attach_type at load time.
1180 */
1181 return 0;
1182}
1183
1184static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
1185 enum bpf_attach_type attach_type)
1186{
1187 /* There are currently no prog types that require specifying
1188 * attach_type at load time.
1189 */
1190 return 0;
1191}
1192
1174/* last field in 'union bpf_attr' used by this command */ 1193/* last field in 'union bpf_attr' used by this command */
1175#define BPF_PROG_LOAD_LAST_FIELD prog_ifindex 1194#define BPF_PROG_LOAD_LAST_FIELD expected_attach_type
1176 1195
1177static int bpf_prog_load(union bpf_attr *attr) 1196static int bpf_prog_load(union bpf_attr *attr)
1178{ 1197{
@@ -1209,11 +1228,16 @@ static int bpf_prog_load(union bpf_attr *attr)
1209 !capable(CAP_SYS_ADMIN)) 1228 !capable(CAP_SYS_ADMIN))
1210 return -EPERM; 1229 return -EPERM;
1211 1230
1231 if (bpf_prog_load_check_attach_type(type, attr->expected_attach_type))
1232 return -EINVAL;
1233
1212 /* plain bpf_prog allocation */ 1234 /* plain bpf_prog allocation */
1213 prog = bpf_prog_alloc(bpf_prog_size(attr->insn_cnt), GFP_USER); 1235 prog = bpf_prog_alloc(bpf_prog_size(attr->insn_cnt), GFP_USER);
1214 if (!prog) 1236 if (!prog)
1215 return -ENOMEM; 1237 return -ENOMEM;
1216 1238
1239 prog->expected_attach_type = attr->expected_attach_type;
1240
1217 prog->aux->offload_requested = !!attr->prog_ifindex; 1241 prog->aux->offload_requested = !!attr->prog_ifindex;
1218 1242
1219 err = security_bpf_prog_alloc(prog->aux); 1243 err = security_bpf_prog_alloc(prog->aux);
@@ -1474,6 +1498,11 @@ static int bpf_prog_attach(const union bpf_attr *attr)
1474 if (IS_ERR(prog)) 1498 if (IS_ERR(prog))
1475 return PTR_ERR(prog); 1499 return PTR_ERR(prog);
1476 1500
1501 if (bpf_prog_attach_check_attach_type(prog, attr->attach_type)) {
1502 bpf_prog_put(prog);
1503 return -EINVAL;
1504 }
1505
1477 cgrp = cgroup_get_from_fd(attr->target_fd); 1506 cgrp = cgroup_get_from_fd(attr->target_fd);
1478 if (IS_ERR(cgrp)) { 1507 if (IS_ERR(cgrp)) {
1479 bpf_prog_put(prog); 1508 bpf_prog_put(prog);
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 8acd2207e412..10024323031d 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1323,7 +1323,7 @@ static int check_ctx_access(struct bpf_verifier_env *env, int insn_idx, int off,
1323 }; 1323 };
1324 1324
1325 if (env->ops->is_valid_access && 1325 if (env->ops->is_valid_access &&
1326 env->ops->is_valid_access(off, size, t, &info)) { 1326 env->ops->is_valid_access(off, size, t, env->prog, &info)) {
1327 /* A non zero info.ctx_field_size indicates that this field is a 1327 /* A non zero info.ctx_field_size indicates that this field is a
1328 * candidate for later verifier transformation to load the whole 1328 * candidate for later verifier transformation to load the whole
1329 * field and then apply a mask when accessed with a narrower 1329 * field and then apply a mask when accessed with a narrower
@@ -2349,7 +2349,7 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
2349 } 2349 }
2350 2350
2351 if (env->ops->get_func_proto) 2351 if (env->ops->get_func_proto)
2352 fn = env->ops->get_func_proto(func_id); 2352 fn = env->ops->get_func_proto(func_id, env->prog);
2353 if (!fn) { 2353 if (!fn) {
2354 verbose(env, "unknown func %s#%d\n", func_id_name(func_id), 2354 verbose(env, "unknown func %s#%d\n", func_id_name(func_id),
2355 func_id); 2355 func_id);
@@ -5572,7 +5572,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
5572 insn = new_prog->insnsi + i + delta; 5572 insn = new_prog->insnsi + i + delta;
5573 } 5573 }
5574patch_call_imm: 5574patch_call_imm:
5575 fn = env->ops->get_func_proto(insn->imm); 5575 fn = env->ops->get_func_proto(insn->imm, env->prog);
5576 /* all functions that have prototype and verifier allowed 5576 /* all functions that have prototype and verifier allowed
5577 * programs to call them, must be real in-kernel functions 5577 * programs to call them, must be real in-kernel functions
5578 */ 5578 */