summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_kern.c
diff options
context:
space:
mode:
authormdf <mdf@FreeBSD.org>2010-08-11 22:10:37 +0000
committermdf <mdf@FreeBSD.org>2010-08-11 22:10:37 +0000
commit0737955344e4f99aa4ecd858ef6e507e591db2a7 (patch)
treede9dacb02fad4c45fd9ea45f38dd4fedbb294977 /sys/vm/vm_kern.c
parentd548943ae909fff2cc91f964186d557895e14bab (diff)
downloadFreeBSD-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.c35
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);
}
/*
OpenPOWER on IntegriCloud