diff options
author | Alan Cox <alc@FreeBSD.org> | 2002-03-17 03:19:31 +0000 |
---|---|---|
committer | Alan Cox <alc@FreeBSD.org> | 2002-03-17 03:19:31 +0000 |
commit | 2f6c16e1e89de3523e1b5f09e53832746d5cf6df (patch) | |
tree | 3fd13b03ff318882c0192220ac50fc5876b14702 /sys | |
parent | 9bc8610af503367fd5a7312075f0260700404eda (diff) | |
download | src-2f6c16e1e89de3523e1b5f09e53832746d5cf6df.tar.gz src-2f6c16e1e89de3523e1b5f09e53832746d5cf6df.zip |
Acquire a read lock on the map inside of vm_map_check_protection() rather
than expecting the caller to do so. This (1) eliminates duplicated code in
kernacc() and useracc() and (2) fixes missing synchronization in munmap().
Notes
Notes:
svn path=/head/; revision=92466
Diffstat (limited to 'sys')
-rw-r--r-- | sys/vm/vm_glue.c | 5 | ||||
-rw-r--r-- | sys/vm/vm_map.c | 6 |
2 files changed, 7 insertions, 4 deletions
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c index 678da3b64402..3263180e5b59 100644 --- a/sys/vm/vm_glue.c +++ b/sys/vm/vm_glue.c @@ -128,9 +128,7 @@ kernacc(addr, len, rw) prot = rw; saddr = trunc_page((vm_offset_t)addr); eaddr = round_page((vm_offset_t)addr + len); - vm_map_lock_read(kernel_map); rv = vm_map_check_protection(kernel_map, saddr, eaddr, prot); - vm_map_unlock_read(kernel_map); return (rv == TRUE); } @@ -163,7 +161,7 @@ useracc(addr, len, rw) return (FALSE); } map = &curproc->p_vmspace->vm_map; - vm_map_lock_read(map); + /* * We save the map hint, and restore it. Useracc appears to distort * the map hint unnecessarily. @@ -172,7 +170,6 @@ useracc(addr, len, rw) rv = vm_map_check_protection(map, trunc_page((vm_offset_t)addr), round_page((vm_offset_t)addr + len), prot); map->hint = save_hint; - vm_map_unlock_read(map); return (rv == TRUE); } diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 3e1b4ab9845c..094372aee544 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -2071,31 +2071,37 @@ vm_map_check_protection(vm_map_t map, vm_offset_t start, vm_offset_t end, GIANT_REQUIRED; + vm_map_lock_read(map); if (!vm_map_lookup_entry(map, start, &tmp_entry)) { + vm_map_unlock_read(map); return (FALSE); } entry = tmp_entry; while (start < end) { if (entry == &map->header) { + vm_map_unlock_read(map); return (FALSE); } /* * No holes allowed! */ if (start < entry->start) { + vm_map_unlock_read(map); return (FALSE); } /* * Check protection associated with entry. */ if ((entry->protection & protection) != protection) { + vm_map_unlock_read(map); return (FALSE); } /* go to next entry */ start = entry->end; entry = entry->next; } + vm_map_unlock_read(map); return (TRUE); } |