Skip to content

Commit 4759acb

Browse files
anakryikogregkh
authored andcommitted
bpf: avoid holding freeze_mutex during mmap operation
commit bc27c52eea189e8f7492d40739b7746d67b65beb upstream. 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]> Signed-off-by: David Sauerwein <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 282d1aa commit 4759acb

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
@@ -813,7 +813,7 @@ static const struct vm_operations_struct bpf_map_default_vmops = {
813813
static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)
814814
{
815815
struct bpf_map *map = filp->private_data;
816-
int err;
816+
int err = 0;
817817

818818
if (!map->ops->map_mmap || map_value_has_spin_lock(map) ||
819819
map_value_has_timer(map) || map_value_has_kptrs(map))
@@ -838,7 +838,12 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)
838838
err = -EACCES;
839839
goto out;
840840
}
841+
bpf_map_write_active_inc(map);
841842
}
843+
out:
844+
mutex_unlock(&map->freeze_mutex);
845+
if (err)
846+
return err;
842847

843848
/* set default open/close callbacks */
844849
vma->vm_ops = &bpf_map_default_vmops;
@@ -849,13 +854,11 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)
849854
vma->vm_flags &= ~VM_MAYWRITE;
850855

851856
err = map->ops->map_mmap(map, vma);
852-
if (err)
853-
goto out;
857+
if (err) {
858+
if (vma->vm_flags & VM_WRITE)
859+
bpf_map_write_active_dec(map);
860+
}
854861

855-
if (vma->vm_flags & VM_MAYWRITE)
856-
bpf_map_write_active_inc(map);
857-
out:
858-
mutex_unlock(&map->freeze_mutex);
859862
return err;
860863
}
861864

0 commit comments

Comments
 (0)