summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_map.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_map.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_map.c')
-rw-r--r--sys/vm/vm_map.c20
1 files changed, 6 insertions, 14 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 0fb7fc1..e2c4c8e 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -2227,6 +2227,8 @@ vm_map_remove(vm_map_t map, vm_offset_t start, vm_offset_t end)
* might be mapped into a larger address space.
*
* NOTE! This code is also called by munmap().
+ *
+ * The map must be locked. A read lock is sufficient.
*/
boolean_t
vm_map_check_protection(vm_map_t map, vm_offset_t start, vm_offset_t end,
@@ -2235,37 +2237,27 @@ vm_map_check_protection(vm_map_t map, vm_offset_t start, vm_offset_t end,
vm_map_entry_t entry;
vm_map_entry_t tmp_entry;
- vm_map_lock_read(map);
- if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
- vm_map_unlock_read(map);
+ if (!vm_map_lookup_entry(map, start, &tmp_entry))
return (FALSE);
- }
entry = tmp_entry;
while (start < end) {
- if (entry == &map->header) {
- vm_map_unlock_read(map);
+ if (entry == &map->header)
return (FALSE);
- }
/*
* No holes allowed!
*/
- if (start < entry->start) {
- vm_map_unlock_read(map);
+ if (start < entry->start)
return (FALSE);
- }
/*
* Check protection associated with entry.
*/
- if ((entry->protection & protection) != protection) {
- vm_map_unlock_read(map);
+ if ((entry->protection & protection) != protection)
return (FALSE);
- }
/* go to next entry */
start = entry->end;
entry = entry->next;
}
- vm_map_unlock_read(map);
return (TRUE);
}
OpenPOWER on IntegriCloud