aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-02-02 08:41:02 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-02-02 08:41:02 -0800
commit178cf7de6f1d3b95407f5a76af249fc924d42576 (patch)
tree4b3e5f3ef6dfa7866fb30811acdc60832a055269 /kernel/bpf/syscall.c
parent89c468263befb4617aaab36ae8c54ba04164c7b0 (diff)
parente36f014edff70fc02b3d3d79cead1d58f289332e (diff)
downloadkernel_replicant_linux-178cf7de6f1d3b95407f5a76af249fc924d42576.tar.gz
kernel_replicant_linux-178cf7de6f1d3b95407f5a76af249fc924d42576.tar.bz2
kernel_replicant_linux-178cf7de6f1d3b95407f5a76af249fc924d42576.zip
Merge 3.19-rc7 into staging-next
We want those fixes in here for testing. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 088ac0b1b106..536edc2be307 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -150,7 +150,7 @@ static int map_lookup_elem(union bpf_attr *attr)
int ufd = attr->map_fd;
struct fd f = fdget(ufd);
struct bpf_map *map;
- void *key, *value;
+ void *key, *value, *ptr;
int err;
if (CHECK_ATTR(BPF_MAP_LOOKUP_ELEM))
@@ -169,20 +169,29 @@ static int map_lookup_elem(union bpf_attr *attr)
if (copy_from_user(key, ukey, map->key_size) != 0)
goto free_key;
- err = -ENOENT;
- rcu_read_lock();
- value = map->ops->map_lookup_elem(map, key);
+ err = -ENOMEM;
+ value = kmalloc(map->value_size, GFP_USER);
if (!value)
- goto err_unlock;
+ goto free_key;
+
+ rcu_read_lock();
+ ptr = map->ops->map_lookup_elem(map, key);
+ if (ptr)
+ memcpy(value, ptr, map->value_size);
+ rcu_read_unlock();
+
+ err = -ENOENT;
+ if (!ptr)
+ goto free_value;
err = -EFAULT;
if (copy_to_user(uvalue, value, map->value_size) != 0)
- goto err_unlock;
+ goto free_value;
err = 0;
-err_unlock:
- rcu_read_unlock();
+free_value:
+ kfree(value);
free_key:
kfree(key);
err_put: