summaryrefslogtreecommitdiff
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 64783da34202..7626b8024471 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -586,9 +586,7 @@ static void bpf_map_mmap_open(struct vm_area_struct *vma)
{
struct bpf_map *map = vma->vm_file->private_data;
- bpf_map_inc_with_uref(map);
-
- if (vma->vm_flags & VM_WRITE) {
+ if (vma->vm_flags & VM_MAYWRITE) {
mutex_lock(&map->freeze_mutex);
map->writecnt++;
mutex_unlock(&map->freeze_mutex);
@@ -600,13 +598,11 @@ static void bpf_map_mmap_close(struct vm_area_struct *vma)
{
struct bpf_map *map = vma->vm_file->private_data;
- if (vma->vm_flags & VM_WRITE) {
+ if (vma->vm_flags & VM_MAYWRITE) {
mutex_lock(&map->freeze_mutex);
map->writecnt--;
mutex_unlock(&map->freeze_mutex);
}
-
- bpf_map_put_with_uref(map);
}
static const struct vm_operations_struct bpf_map_default_vmops = {
@@ -635,14 +631,16 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)
/* set default open/close callbacks */
vma->vm_ops = &bpf_map_default_vmops;
vma->vm_private_data = map;
+ vma->vm_flags &= ~VM_MAYEXEC;
+ if (!(vma->vm_flags & VM_WRITE))
+ /* disallow re-mapping with PROT_WRITE */
+ vma->vm_flags &= ~VM_MAYWRITE;
err = map->ops->map_mmap(map, vma);
if (err)
goto out;
- bpf_map_inc_with_uref(map);
-
- if (vma->vm_flags & VM_WRITE)
+ if (vma->vm_flags & VM_MAYWRITE)
map->writecnt++;
out:
mutex_unlock(&map->freeze_mutex);
@@ -2285,7 +2283,7 @@ static void bpf_link_show_fdinfo(struct seq_file *m, struct file *filp)
}
#endif
-const struct file_operations bpf_link_fops = {
+static const struct file_operations bpf_link_fops = {
#ifdef CONFIG_PROC_FS
.show_fdinfo = bpf_link_show_fdinfo,
#endif
@@ -3630,8 +3628,10 @@ static int link_update(union bpf_attr *attr)
return PTR_ERR(link);
new_prog = bpf_prog_get(attr->link_update.new_prog_fd);
- if (IS_ERR(new_prog))
- return PTR_ERR(new_prog);
+ if (IS_ERR(new_prog)) {
+ ret = PTR_ERR(new_prog);
+ goto out_put_link;
+ }
if (flags & BPF_F_REPLACE) {
old_prog = bpf_prog_get(attr->link_update.old_prog_fd);
@@ -3640,6 +3640,9 @@ static int link_update(union bpf_attr *attr)
old_prog = NULL;
goto out_put_progs;
}
+ } else if (attr->link_update.old_prog_fd) {
+ ret = -EINVAL;
+ goto out_put_progs;
}
#ifdef CONFIG_CGROUP_BPF
@@ -3655,6 +3658,8 @@ out_put_progs:
bpf_prog_put(old_prog);
if (ret)
bpf_prog_put(new_prog);
+out_put_link:
+ bpf_link_put(link);
return ret;
}