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.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index b29e6dc44650..0834958f1dc4 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -682,7 +682,7 @@ static void *__bpf_copy_key(void __user *ukey, u64 key_size)
682} 682}
683 683
684/* last field in 'union bpf_attr' used by this command */ 684/* last field in 'union bpf_attr' used by this command */
685#define BPF_MAP_LOOKUP_ELEM_LAST_FIELD value 685#define BPF_MAP_LOOKUP_ELEM_LAST_FIELD flags
686 686
687static int map_lookup_elem(union bpf_attr *attr) 687static int map_lookup_elem(union bpf_attr *attr)
688{ 688{
@@ -698,6 +698,9 @@ static int map_lookup_elem(union bpf_attr *attr)
698 if (CHECK_ATTR(BPF_MAP_LOOKUP_ELEM)) 698 if (CHECK_ATTR(BPF_MAP_LOOKUP_ELEM))
699 return -EINVAL; 699 return -EINVAL;
700 700
701 if (attr->flags & ~BPF_F_LOCK)
702 return -EINVAL;
703
701 f = fdget(ufd); 704 f = fdget(ufd);
702 map = __bpf_map_get(f); 705 map = __bpf_map_get(f);
703 if (IS_ERR(map)) 706 if (IS_ERR(map))
@@ -708,6 +711,12 @@ static int map_lookup_elem(union bpf_attr *attr)
708 goto err_put; 711 goto err_put;
709 } 712 }
710 713
714 if ((attr->flags & BPF_F_LOCK) &&
715 !map_value_has_spin_lock(map)) {
716 err = -EINVAL;
717 goto err_put;
718 }
719
711 key = __bpf_copy_key(ukey, map->key_size); 720 key = __bpf_copy_key(ukey, map->key_size);
712 if (IS_ERR(key)) { 721 if (IS_ERR(key)) {
713 err = PTR_ERR(key); 722 err = PTR_ERR(key);
@@ -758,7 +767,13 @@ static int map_lookup_elem(union bpf_attr *attr)
758 err = -ENOENT; 767 err = -ENOENT;
759 } else { 768 } else {
760 err = 0; 769 err = 0;
761 copy_map_value(map, value, ptr); 770 if (attr->flags & BPF_F_LOCK)
771 /* lock 'ptr' and copy everything but lock */
772 copy_map_value_locked(map, value, ptr, true);
773 else
774 copy_map_value(map, value, ptr);
775 /* mask lock, since value wasn't zero inited */
776 check_and_init_map_lock(map, value);
762 } 777 }
763 rcu_read_unlock(); 778 rcu_read_unlock();
764 } 779 }
@@ -818,6 +833,12 @@ static int map_update_elem(union bpf_attr *attr)
818 goto err_put; 833 goto err_put;
819 } 834 }
820 835
836 if ((attr->flags & BPF_F_LOCK) &&
837 !map_value_has_spin_lock(map)) {
838 err = -EINVAL;
839 goto err_put;
840 }
841
821 key = __bpf_copy_key(ukey, map->key_size); 842 key = __bpf_copy_key(ukey, map->key_size);
822 if (IS_ERR(key)) { 843 if (IS_ERR(key)) {
823 err = PTR_ERR(key); 844 err = PTR_ERR(key);