summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authortedu <tedu@openbsd.org>2015-09-26 15:37:28 +0000
committertedu <tedu@openbsd.org>2015-09-26 15:37:28 +0000
commit39b0071161235cf072a988f78d81fb4d7654a4eb (patch)
tree1990a73fce12980231885f4753799ef0d6cb0a8b /sys
parentWe don't need no stinking "EXAMPLE OF THE DSA" or README (the credits are (diff)
downloadwireguard-openbsd-39b0071161235cf072a988f78d81fb4d7654a4eb.tar.xz
wireguard-openbsd-39b0071161235cf072a988f78d81fb4d7654a4eb.zip
matthew noticed there's a race where we are using the kernel lock to tie
together the unmap and map portions of a fixed mmap. make this explicit by pulling the lock up higher. in preparation for unlocking the syscall. there's still (always has been) a race where if the unmap sleeps, another mmap may see partial results because the map lock isn't held througout. another problem, another day.
Diffstat (limited to 'sys')
-rw-r--r--sys/uvm/uvm_mmap.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c
index c473046c7f4..92498a4e397 100644
--- a/sys/uvm/uvm_mmap.c
+++ b/sys/uvm/uvm_mmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_mmap.c,v 1.115 2015/09/23 00:16:44 guenther Exp $ */
+/* $OpenBSD: uvm_mmap.c,v 1.116 2015/09/26 15:37:28 tedu Exp $ */
/* $NetBSD: uvm_mmap.c,v 1.49 2001/02/18 21:19:08 chs Exp $ */
/*
@@ -513,8 +513,12 @@ is_anon: /* label for SunOS style /dev/zero */
}
}
maxprot = PROT_MASK;
+ if ((flags & (MAP_FIXED|__MAP_NOREPLACE)) == MAP_FIXED)
+ KERNEL_LOCK();
error = uvm_mmapanon(&p->p_vmspace->vm_map, &addr, size, prot, maxprot,
flags, p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur, p);
+ if ((flags & (MAP_FIXED|__MAP_NOREPLACE)) == MAP_FIXED)
+ KERNEL_UNLOCK();
}
if (error == 0)
@@ -987,9 +991,8 @@ uvm_mmapanon(vm_map_t map, vaddr_t *addr, vsize_t size, vm_prot_t prot,
uvmflag |= UVM_FLAG_FIXED;
if ((flags & __MAP_NOREPLACE) == 0) {
- KERNEL_LOCK();
+ /* KERNEL_LOCK held above */
uvm_unmap(map, *addr, *addr + size); /* zap! */
- KERNEL_UNLOCK();
}
}