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.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 57f4d076141b..43727ed0d94a 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -103,6 +103,7 @@ int bpf_check_uarg_tail_zero(void __user *uaddr,
103const struct bpf_map_ops bpf_map_offload_ops = { 103const struct bpf_map_ops bpf_map_offload_ops = {
104 .map_alloc = bpf_map_offload_map_alloc, 104 .map_alloc = bpf_map_offload_map_alloc,
105 .map_free = bpf_map_offload_map_free, 105 .map_free = bpf_map_offload_map_free,
106 .map_check_btf = map_check_no_btf,
106}; 107};
107 108
108static struct bpf_map *find_and_alloc_map(union bpf_attr *attr) 109static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
@@ -455,6 +456,34 @@ static int bpf_obj_name_cpy(char *dst, const char *src)
455 return 0; 456 return 0;
456} 457}
457 458
459int map_check_no_btf(const struct bpf_map *map,
460 const struct btf_type *key_type,
461 const struct btf_type *value_type)
462{
463 return -ENOTSUPP;
464}
465
466static int map_check_btf(const struct bpf_map *map, const struct btf *btf,
467 u32 btf_key_id, u32 btf_value_id)
468{
469 const struct btf_type *key_type, *value_type;
470 u32 key_size, value_size;
471 int ret = 0;
472
473 key_type = btf_type_id_size(btf, &btf_key_id, &key_size);
474 if (!key_type || key_size != map->key_size)
475 return -EINVAL;
476
477 value_type = btf_type_id_size(btf, &btf_value_id, &value_size);
478 if (!value_type || value_size != map->value_size)
479 return -EINVAL;
480
481 if (map->ops->map_check_btf)
482 ret = map->ops->map_check_btf(map, key_type, value_type);
483
484 return ret;
485}
486
458#define BPF_MAP_CREATE_LAST_FIELD btf_value_type_id 487#define BPF_MAP_CREATE_LAST_FIELD btf_value_type_id
459/* called via syscall */ 488/* called via syscall */
460static int map_create(union bpf_attr *attr) 489static int map_create(union bpf_attr *attr)
@@ -489,8 +518,7 @@ static int map_create(union bpf_attr *attr)
489 atomic_set(&map->refcnt, 1); 518 atomic_set(&map->refcnt, 1);
490 atomic_set(&map->usercnt, 1); 519 atomic_set(&map->usercnt, 1);
491 520
492 if (bpf_map_support_seq_show(map) && 521 if (attr->btf_key_type_id || attr->btf_value_type_id) {
493 (attr->btf_key_type_id || attr->btf_value_type_id)) {
494 struct btf *btf; 522 struct btf *btf;
495 523
496 if (!attr->btf_key_type_id || !attr->btf_value_type_id) { 524 if (!attr->btf_key_type_id || !attr->btf_value_type_id) {
@@ -504,8 +532,8 @@ static int map_create(union bpf_attr *attr)
504 goto free_map_nouncharge; 532 goto free_map_nouncharge;
505 } 533 }
506 534
507 err = map->ops->map_check_btf(map, btf, attr->btf_key_type_id, 535 err = map_check_btf(map, btf, attr->btf_key_type_id,
508 attr->btf_value_type_id); 536 attr->btf_value_type_id);
509 if (err) { 537 if (err) {
510 btf_put(btf); 538 btf_put(btf);
511 goto free_map_nouncharge; 539 goto free_map_nouncharge;