diff options
author | mdf <mdf@FreeBSD.org> | 2010-08-11 22:10:37 +0000 |
---|---|---|
committer | mdf <mdf@FreeBSD.org> | 2010-08-11 22:10:37 +0000 |
commit | 0737955344e4f99aa4ecd858ef6e507e591db2a7 (patch) | |
tree | de9dacb02fad4c45fd9ea45f38dd4fedbb294977 /sys/vm/vm_kern.c | |
parent | d548943ae909fff2cc91f964186d557895e14bab (diff) | |
download | FreeBSD-src-0737955344e4f99aa4ecd858ef6e507e591db2a7.zip FreeBSD-src-0737955344e4f99aa4ecd858ef6e507e591db2a7.tar.gz |
Rework memguard(9) to reserve significantly more KVA to detect
use-after-free over a longer time. Also release the backing pages of
a guarded allocation at free(9) time to reduce the overhead of using
memguard(9). Allow setting and varying the malloc type at run-time.
Add knobs to allow:
- randomly guarding memory
- adding un-backed KVA guard pages to detect underflow and overflow
- a lower limit on the size of allocations that are guarded
Reviewed by: alc
Reviewed by: brueffer, Ulrich Spörlein <uqs spoerlein net> (man page)
Silence from: -arch
Approved by: zml (mentor)
MFC after: 1 month
Diffstat (limited to 'sys/vm/vm_kern.c')
-rw-r--r-- | sys/vm/vm_kern.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index 95a4e9d..0b840a4 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -301,11 +301,8 @@ kmem_malloc(map, size, flags) vm_size_t size; int flags; { - vm_offset_t offset, i; - vm_map_entry_t entry; vm_offset_t addr; - vm_page_t m; - int pflags; + int i, rv; size = round_page(size); addr = vm_map_min(map); @@ -338,6 +335,30 @@ kmem_malloc(map, size, flags) return (0); } } + + rv = kmem_back(map, addr, size, flags); + vm_map_unlock(map); + return (rv == KERN_SUCCESS ? addr : 0); +} + +/* + * kmem_back: + * + * Allocate physical pages for the specified virtual address range. + */ +int +kmem_back(vm_map_t map, vm_offset_t addr, vm_size_t size, int flags) +{ + vm_offset_t offset, i; + vm_map_entry_t entry; + vm_page_t m; + int pflags; + + /* + * XXX the map must be locked for write on entry, but there's + * no easy way to assert that. + */ + offset = addr - VM_MIN_KERNEL_ADDRESS; vm_object_reference(kmem_object); vm_map_insert(map, kmem_object, offset, addr, addr + size, @@ -385,8 +406,7 @@ retry: } VM_OBJECT_UNLOCK(kmem_object); vm_map_delete(map, addr, addr + size); - vm_map_unlock(map); - return (0); + return (KERN_NO_SPACE); } if (flags & M_ZERO && (m->flags & PG_ZERO) == 0) pmap_zero_page(m); @@ -429,9 +449,8 @@ retry: vm_page_wakeup(m); } VM_OBJECT_UNLOCK(kmem_object); - vm_map_unlock(map); - return (addr); + return (KERN_SUCCESS); } /* |