aboutsummaryrefslogtreecommitdiff
path: root/sys/vm
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2020-06-26 16:16:25 +0000
committerMark Johnston <markj@FreeBSD.org>2020-06-26 16:16:25 +0000
commit08985893c431a0806f1ed8a919ce027e94a866b7 (patch)
treef0d8b42fa2450fd2fa005566e5d0e1365c7ec370 /sys/vm
parentd6e61273ab60168bad341ee90b7044c08ab595d2 (diff)
Notes
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_fault.c5
-rw-r--r--sys/vm/vm_map.c12
-rw-r--r--sys/vm/vm_map.h11
-rw-r--r--sys/vm/vm_mmap.c25
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);
/*