Skip to content

Commit bc27c52

Browse files
anakryikoAlexei Starovoitov
authored andcommitted
bpf: avoid holding freeze_mutex during mmap operation
We use map->freeze_mutex to prevent races between map_freeze() and memory mapping BPF map contents with writable permissions. The way we naively do this means we'll hold freeze_mutex for entire duration of all the mm and VMA manipulations, which is completely unnecessary. This can potentially also lead to deadlocks, as reported by syzbot in [0]. So, instead, hold freeze_mutex only during writeability checks, bump (proactively) "write active" count for the map, unlock the mutex and proceed with mmap logic. And only if something went wrong during mmap logic, then undo that "write active" counter increment. [0] https://lore.kernel.org/bpf/[email protected]/ Fixes: fc97022 ("bpf: Add mmap() support for BPF_MAP_TYPE_ARRAY") Reported-by: [email protected] Signed-off-by: Andrii Nakryiko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 98671a0 commit bc27c52

File tree

1 file changed

+10
-7
lines changed

1 file changed

+10
-7
lines changed

kernel/bpf/syscall.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,7 @@ static const struct vm_operations_struct bpf_map_default_vmops = {
10351035
static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)
10361036
{
10371037
struct bpf_map *map = filp->private_data;
1038-
int err;
1038+
int err = 0;
10391039

10401040
if (!map->ops->map_mmap || !IS_ERR_OR_NULL(map->record))
10411041
return -ENOTSUPP;
@@ -1059,7 +1059,12 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)
10591059
err = -EACCES;
10601060
goto out;
10611061
}
1062+
bpf_map_write_active_inc(map);
10621063
}
1064+
out:
1065+
mutex_unlock(&map->freeze_mutex);
1066+
if (err)
1067+
return err;
10631068

10641069
/* set default open/close callbacks */
10651070
vma->vm_ops = &bpf_map_default_vmops;
@@ -1076,13 +1081,11 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)
10761081
vm_flags_clear(vma, VM_MAYWRITE);
10771082

10781083
err = map->ops->map_mmap(map, vma);
1079-
if (err)
1080-
goto out;
1084+
if (err) {
1085+
if (vma->vm_flags & VM_WRITE)
1086+
bpf_map_write_active_dec(map);
1087+
}
10811088

1082-
if (vma->vm_flags & VM_WRITE)
1083-
bpf_map_write_active_inc(map);
1084-
out:
1085-
mutex_unlock(&map->freeze_mutex);
10861089
return err;
10871090
}
10881091

0 commit comments

Comments
 (0)