diff options
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r-- | kernel/bpf/syscall.c | 21 |
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 | ||
466 | static int map_check_btf(const struct bpf_map *map, const struct btf *btf, | 466 | static 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 | } |