diff options
| author | Mark Johnston <markj@FreeBSD.org> | 2020-06-26 16:16:25 +0000 |
|---|---|---|
| committer | Mark Johnston <markj@FreeBSD.org> | 2020-06-26 16:16:25 +0000 |
| commit | 08985893c431a0806f1ed8a919ce027e94a866b7 (patch) | |
| tree | f0d8b42fa2450fd2fa005566e5d0e1365c7ec370 /sys/vm | |
| parent | d6e61273ab60168bad341ee90b7044c08ab595d2 (diff) | |
Notes
Diffstat (limited to 'sys/vm')
| -rw-r--r-- | sys/vm/vm_fault.c | 5 | ||||
| -rw-r--r-- | sys/vm/vm_map.c | 12 | ||||
| -rw-r--r-- | sys/vm/vm_map.h | 11 | ||||
| -rw-r--r-- | sys/vm/vm_mmap.c | 25 |
4 files changed, 24 insertions, 29 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 9e3ec0975c82..cf2db256eaa3 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -1643,10 +1643,7 @@ vm_fault_quick_hold_pages(vm_map_t map, vm_offset_t addr, vm_size_t len, end = round_page(addr + len); addr = trunc_page(addr); - /* - * Check for illegal addresses. - */ - if (addr < vm_map_min(map) || addr > end || end > vm_map_max(map)) + if (!vm_map_range_valid(map, addr, end)) return (-1); if (atop(end - addr) > max_count) diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 68ca69ae8d50..9e48ead1a867 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -1450,8 +1450,7 @@ vm_map_insert(vm_map_t map, vm_object_t object, vm_ooffset_t offset, /* * Check that the start and end points are not bogus. */ - if (start < vm_map_min(map) || end > vm_map_max(map) || - start >= end) + if (start == end || !vm_map_range_valid(map, start, end)) return (KERN_INVALID_ADDRESS); /* @@ -1986,9 +1985,7 @@ again: goto done; } } else if ((cow & MAP_REMAP) != 0) { - if (*addr < vm_map_min(map) || - *addr + length > vm_map_max(map) || - *addr + length <= length) { + if (!vm_map_range_valid(map, *addr, *addr + length)) { rv = KERN_INVALID_ADDRESS; goto done; } @@ -4163,9 +4160,8 @@ vm_map_stack_locked(vm_map_t map, vm_offset_t addrbos, vm_size_t max_ssize, KASSERT(orient != (MAP_STACK_GROWS_DOWN | MAP_STACK_GROWS_UP), ("bi-dir stack")); - if (addrbos < vm_map_min(map) || - addrbos + max_ssize > vm_map_max(map) || - addrbos + max_ssize <= addrbos) + if (max_ssize == 0 || + !vm_map_range_valid(map, addrbos, addrbos + max_ssize)) return (KERN_INVALID_ADDRESS); sgp = ((curproc->p_flag2 & P2_STKGAP_DISABLE) != 0 || (curproc->p_fctl0 & NT_FREEBSD_FCTL_STKGAP_DISABLE) != 0) ? 0 : diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h index c4d31a500104..fbce5e22e6d9 100644 --- a/sys/vm/vm_map.h +++ b/sys/vm/vm_map.h @@ -250,6 +250,17 @@ vm_map_modflags(vm_map_t map, vm_flags_t set, vm_flags_t clear) { map->flags = (map->flags | set) & ~clear; } + +static inline bool +vm_map_range_valid(vm_map_t map, vm_offset_t start, vm_offset_t end) +{ + if (end < start) + return (false); + if (start < vm_map_min(map) || end > vm_map_max(map)) + return (false); + return (true); +} + #endif /* KLD_MODULE */ #endif /* _KERNEL */ diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index b5f24c4b4b69..d919cbda9d6a 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -298,10 +298,7 @@ kern_mmap_fpcheck(struct thread *td, uintptr_t addr0, size_t size, int prot, return (EINVAL); /* Address range must be all in user VM space. */ - if (addr < vm_map_min(&vms->vm_map) || - addr + size > vm_map_max(&vms->vm_map)) - return (EINVAL); - if (addr + size < addr) + if (!vm_map_range_valid(&vms->vm_map, addr, addr + size)) return (EINVAL); #ifdef MAP_32BIT if (flags & MAP_32BIT && addr + size > MAP_32BIT_MAX_ADDR) @@ -534,7 +531,7 @@ kern_munmap(struct thread *td, uintptr_t addr0, size_t size) vm_map_entry_t entry; bool pmc_handled; #endif - vm_offset_t addr; + vm_offset_t addr, end; vm_size_t pageoff; vm_map_t map; @@ -546,15 +543,11 @@ kern_munmap(struct thread *td, uintptr_t addr0, size_t size) addr -= pageoff; size += pageoff; size = (vm_size_t) round_page(size); - if (addr + size < addr) - return (EINVAL); - - /* - * Check for illegal addresses. Watch out for address wrap... - */ + end = addr + size; map = &td->td_proc->p_vmspace->vm_map; - if (addr < vm_map_min(map) || addr + size > vm_map_max(map)) + if (!vm_map_range_valid(map, addr, end)) return (EINVAL); + vm_map_lock(map); #ifdef HWPMC_HOOKS pmc_handled = false; @@ -566,7 +559,7 @@ kern_munmap(struct thread *td, uintptr_t addr0, size_t size) */ pkm.pm_address = (uintptr_t) NULL; if (vm_map_lookup_entry(map, addr, &entry)) { - for (; entry->start < addr + size; + for (; entry->start < end; entry = entry->next) { if (vm_map_check_protection(map, entry->start, entry->end, VM_PROT_EXECUTE) == TRUE) { @@ -578,7 +571,7 @@ kern_munmap(struct thread *td, uintptr_t addr0, size_t size) } } #endif - vm_map_delete(map, addr, addr + size); + vm_map_delete(map, addr, end); #ifdef HWPMC_HOOKS if (__predict_false(pmc_handled)) { @@ -715,9 +708,7 @@ kern_madvise(struct thread *td, uintptr_t addr0, size_t len, int behav) */ map = &td->td_proc->p_vmspace->vm_map; addr = addr0; - if (addr < vm_map_min(map) || addr + len > vm_map_max(map)) - return (EINVAL); - if ((addr + len) < addr) + if (!vm_map_range_valid(map, addr, addr + len)) return (EINVAL); /* |
