summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_mmap.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-11-10 01:37:40 +0000
committeralc <alc@FreeBSD.org>2003-11-10 01:37:40 +0000
commitfa4ea5d2f2c4f2808206b802fa09b5ee6ffb7631 (patch)
tree9f9445306d056c8d74e579030ddec7cb2c11e1bc /sys/vm/vm_mmap.c
parent918610ef5e152cf4feecdc66bece5d06153b9668 (diff)
downloadFreeBSD-src-fa4ea5d2f2c4f2808206b802fa09b5ee6ffb7631.zip
FreeBSD-src-fa4ea5d2f2c4f2808206b802fa09b5ee6ffb7631.tar.gz
- The Open Group Base Specifications Issue 6 specifies that an munmap(2)
must return EINVAL if size is zero. Submitted by: tegge - In order to avoid a race condition in multithreaded applications, the check and removal operations by munmap(2) must be in the same critical section. To accomodate this, vm_map_check_protection() is modified to require its caller to obtain at least a read lock on the map.
Diffstat (limited to 'sys/vm/vm_mmap.c')
-rw-r--r--sys/vm/vm_mmap.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 95e335a..9025c46 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -585,6 +585,8 @@ munmap(td, uap)
addr = (vm_offset_t) uap->addr;
size = uap->len;
+ if (size == 0)
+ return (EINVAL);
pageoff = (addr & PAGE_MASK);
addr -= pageoff;
@@ -593,23 +595,23 @@ munmap(td, uap)
if (addr + size < addr)
return (EINVAL);
- if (size == 0)
- return (0);
-
/*
* Check for illegal addresses. Watch out for address wrap...
*/
map = &td->td_proc->p_vmspace->vm_map;
if (addr < vm_map_min(map) || addr + size > vm_map_max(map))
return (EINVAL);
+ vm_map_lock(map);
/*
* Make sure entire range is allocated.
*/
- if (!vm_map_check_protection(map, addr, addr + size, VM_PROT_NONE))
+ if (!vm_map_check_protection(map, addr, addr + size, VM_PROT_NONE)) {
+ vm_map_unlock(map);
return (EINVAL);
-
+ }
/* returns nothing but KERN_SUCCESS anyway */
- (void) vm_map_remove(map, addr, addr + size);
+ vm_map_delete(map, addr, addr + size);
+ vm_map_unlock(map);
return (0);
}
OpenPOWER on IntegriCloud