diff options
author | alc <alc@FreeBSD.org> | 2003-11-10 01:37:40 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2003-11-10 01:37:40 +0000 |
commit | fa4ea5d2f2c4f2808206b802fa09b5ee6ffb7631 (patch) | |
tree | 9f9445306d056c8d74e579030ddec7cb2c11e1bc /sys/vm/vm_map.c | |
parent | 918610ef5e152cf4feecdc66bece5d06153b9668 (diff) | |
download | FreeBSD-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.c | 20 |
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); } |