diff options
author | alc <alc@FreeBSD.org> | 2007-10-22 05:21:05 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2007-10-22 05:21:05 +0000 |
commit | bb82ce71e336573e86421f937b90184001d67236 (patch) | |
tree | 87f54c9be7bf4feca696f5094058e6a1044e9a27 /sys/vm/vm_map.c | |
parent | 9dec415fef268455335c088626d24f3cd5dd26fc (diff) | |
download | FreeBSD-src-bb82ce71e336573e86421f937b90184001d67236.zip FreeBSD-src-bb82ce71e336573e86421f937b90184001d67236.tar.gz |
Correct an error in vm_map_sync(), nee vm_map_clean(), that has existed
since revision 1.1. Specifically, neither traversal of the vm map checks
whether the end of the vm map has been reached. Consequently, the first
traversal can wrap around and bogusly return an error.
This error has gone unnoticed for so long because no one had ever before
tried msync(2)ing a region above the stack.
Reported by: peter
MFC after: 1 week
Diffstat (limited to 'sys/vm/vm_map.c')
-rw-r--r-- | sys/vm/vm_map.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index cc6628b..4b31fb3 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -2204,7 +2204,8 @@ vm_map_sync( /* * Make a first pass to check for user-wired memory and holes. */ - for (current = entry; current->start < end; current = current->next) { + for (current = entry; current != &map->header && current->start < end; + current = current->next) { if (invalidate && (current->eflags & MAP_ENTRY_USER_WIRED)) { vm_map_unlock_read(map); return (KERN_INVALID_ARGUMENT); @@ -2224,7 +2225,8 @@ vm_map_sync( * Make a second pass, cleaning/uncaching pages from the indicated * objects as we go. */ - for (current = entry; current->start < end; current = current->next) { + for (current = entry; current != &map->header && current->start < end; + current = current->next) { offset = current->offset + (start - current->start); size = (end <= current->end ? end : current->end) - start; if (current->eflags & MAP_ENTRY_IS_SUB_MAP) { |