diff options
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r-- | kernel/bpf/syscall.c | 36 |
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, | |||
103 | const struct bpf_map_ops bpf_map_offload_ops = { | 103 | const 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 | ||
108 | static struct bpf_map *find_and_alloc_map(union bpf_attr *attr) | 109 | static 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 | ||
459 | int 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 | |||
466 | static 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 */ |
460 | static int map_create(union bpf_attr *attr) | 489 | static 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; |