summaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index b155cd17c1bd..ebf0a673cb83 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -463,7 +463,7 @@ int map_check_no_btf(const struct bpf_map *map,
463 return -ENOTSUPP; 463 return -ENOTSUPP;
464} 464}
465 465
466static int map_check_btf(const struct bpf_map *map, const struct btf *btf, 466static int map_check_btf(struct bpf_map *map, const struct btf *btf,
467 u32 btf_key_id, u32 btf_value_id) 467 u32 btf_key_id, u32 btf_value_id)
468{ 468{
469 const struct btf_type *key_type, *value_type; 469 const struct btf_type *key_type, *value_type;
@@ -478,6 +478,21 @@ static int map_check_btf(const struct bpf_map *map, const struct btf *btf,
478 if (!value_type || value_size != map->value_size) 478 if (!value_type || value_size != map->value_size)
479 return -EINVAL; 479 return -EINVAL;
480 480
481 map->spin_lock_off = btf_find_spin_lock(btf, value_type);
482
483 if (map_value_has_spin_lock(map)) {
484 if (map->map_type != BPF_MAP_TYPE_HASH &&
485 map->map_type != BPF_MAP_TYPE_ARRAY)
486 return -ENOTSUPP;
487 if (map->spin_lock_off + sizeof(struct bpf_spin_lock) >
488 map->value_size) {
489 WARN_ONCE(1,
490 "verifier bug spin_lock_off %d value_size %d\n",
491 map->spin_lock_off, map->value_size);
492 return -EFAULT;
493 }
494 }
495
481 if (map->ops->map_check_btf) 496 if (map->ops->map_check_btf)
482 ret = map->ops->map_check_btf(map, btf, key_type, value_type); 497 ret = map->ops->map_check_btf(map, btf, key_type, value_type);
483 498
@@ -542,6 +557,8 @@ static int map_create(union bpf_attr *attr)
542 map->btf = btf; 557 map->btf = btf;
543 map->btf_key_type_id = attr->btf_key_type_id; 558 map->btf_key_type_id = attr->btf_key_type_id;
544 map->btf_value_type_id = attr->btf_value_type_id; 559 map->btf_value_type_id = attr->btf_value_type_id;
560 } else {
561 map->spin_lock_off = -EINVAL;
545 } 562 }
546 563
547 err = security_bpf_map_alloc(map); 564 err = security_bpf_map_alloc(map);
@@ -740,7 +757,7 @@ static int map_lookup_elem(union bpf_attr *attr)
740 err = -ENOENT; 757 err = -ENOENT;
741 } else { 758 } else {
742 err = 0; 759 err = 0;
743 memcpy(value, ptr, value_size); 760 copy_map_value(map, value, ptr);
744 } 761 }
745 rcu_read_unlock(); 762 rcu_read_unlock();
746 } 763 }