summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorariane <ariane@openbsd.org>2011-05-29 15:18:19 +0000
committerariane <ariane@openbsd.org>2011-05-29 15:18:19 +0000
commit6ffe1711590840e2459ff1709973e670a927e9be (patch)
tree698b3ca815d731e11890a9d70718474edec8d7fb
parentsync (diff)
downloadwireguard-openbsd-6ffe1711590840e2459ff1709973e670a927e9be.tar.xz
wireguard-openbsd-6ffe1711590840e2459ff1709973e670a927e9be.zip
Fix parameter range clamping in vmmap routines.
The old VM_MAP_RANGE_CHECK macro was wrong and caused code to be unreadable (argument altering macros are harmful). Each function now treats the memory range outside the map as it would treat free memory: if it would error on being given free memory, it'll error in a similar fashion when the start,end parameters fall outside the map. If it would accept free memory in its argument range, it'll silently accept the outside-map memory too. Confirmed to help ports build machines.
-rw-r--r--sys/uvm/uvm_map.c61
1 files changed, 37 insertions, 24 deletions
diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c
index ed9930f42f0..58406bd6efd 100644
--- a/sys/uvm/uvm_map.c
+++ b/sys/uvm/uvm_map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_map.c,v 1.136 2011/05/24 15:27:36 ariane Exp $ */
+/* $OpenBSD: uvm_map.c,v 1.137 2011/05/29 15:18:19 ariane Exp $ */
/* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
/*
@@ -477,16 +477,6 @@ uvm_mapent_addr_remove(struct vm_map *map, struct vm_map_entry *entry)
}
/*
- * Clamp start and end to map boundaries.
- */
-#define VM_MAP_RANGE_CHECK(_map, _start, _end) \
- do { \
- (_start) = MAX((_start), vm_map_min((_map))); \
- (_end) = MIN((_end), vm_map_max((_map))); \
- (_start) = MIN((_start), (_end)); \
- } while (0)
-
-/*
* uvm_map_reference: add reference to a map
*
* XXX check map reference counter lock
@@ -1795,8 +1785,9 @@ uvm_unmap_remove(struct vm_map *map, vaddr_t start, vaddr_t end,
{
struct vm_map_entry *prev_hint, *next, *entry;
- VM_MAP_RANGE_CHECK(map, start, end);
- if (start == end)
+ start = MAX(start, map->min_offset);
+ end = MIN(end, map->max_offset);
+ if (start >= end)
return;
if ((map->flags & VM_MAP_INTRSAFE) == 0)
@@ -2130,12 +2121,17 @@ uvm_map_pageable(struct vm_map *map, vaddr_t start, vaddr_t end,
struct vm_map_entry *first, *last, *tmp;
int error;
+ if (start > end)
+ return EINVAL;
+ if (start < map->min_offset)
+ return EFAULT; /* why? see first XXX below */
+ if (end > map->max_offset)
+ return EINVAL; /* why? see second XXX below */
+
KASSERT(map->flags & VM_MAP_PAGEABLE);
if ((lockflags & UVM_LK_ENTER) == 0)
vm_map_lock(map);
- VM_MAP_RANGE_CHECK(map, start, end);
-
/*
* Find first entry.
*
@@ -2917,8 +2913,11 @@ uvm_map_protect(struct vm_map *map, vaddr_t start, vaddr_t end,
vm_prot_t mask;
int error;
- VM_MAP_RANGE_CHECK(map, start, end);
- if (start == end)
+ if (start > end)
+ return EINVAL;
+ start = MAX(start, map->min_offset);
+ end = MIN(end, map->max_offset);
+ if (start >= end)
return 0;
error = 0;
@@ -3685,9 +3684,11 @@ uvm_map_submap(struct vm_map *map, vaddr_t start, vaddr_t end,
struct vm_map_entry *entry;
int result;
- vm_map_lock(map);
+ if (start > map->max_offset || end > map->max_offset ||
+ start < map->min_offset || end < map->min_offset)
+ return EINVAL;
- VM_MAP_RANGE_CHECK(map, start, end);
+ vm_map_lock(map);
if (uvm_map_lookup_entry(map, start, &entry)) {
UVM_MAP_CLIP_START(map, entry, start);
@@ -3826,9 +3827,14 @@ uvm_map_inherit(struct vm_map *map, vaddr_t start, vaddr_t end,
return (EINVAL);
}
- vm_map_lock(map);
+ if (start > end)
+ return EINVAL;
+ start = MAX(start, map->min_offset);
+ end = MIN(end, map->max_offset);
+ if (start >= end)
+ return 0;
- VM_MAP_RANGE_CHECK(map, start, end);
+ vm_map_lock(map);
entry = uvm_map_entrybyaddr(&map->addr, start);
if (entry->end > start)
@@ -3870,9 +3876,14 @@ uvm_map_advice(struct vm_map *map, vaddr_t start, vaddr_t end, int new_advice)
return (EINVAL);
}
- vm_map_lock(map);
+ if (start > end)
+ return EINVAL;
+ start = MAX(start, map->min_offset);
+ end = MIN(end, map->max_offset);
+ if (start >= end)
+ return 0;
- VM_MAP_RANGE_CHECK(map, start, end);
+ vm_map_lock(map);
entry = uvm_map_entrybyaddr(&map->addr, start);
if (entry != NULL && entry->end > start)
@@ -4117,8 +4128,10 @@ uvm_map_clean(struct vm_map *map, vaddr_t start, vaddr_t end, int flags)
KASSERT((flags & (PGO_FREE|PGO_DEACTIVATE)) !=
(PGO_FREE|PGO_DEACTIVATE));
+ if (start > end || start < map->min_offset || end > map->max_offset)
+ return EINVAL;
+
vm_map_lock_read(map);
- VM_MAP_RANGE_CHECK(map, start, end);
first = uvm_map_entrybyaddr(&map->addr, start);
/*