summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_malloc.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/kern/kern_malloc.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/kern/kern_malloc.c')
-rw-r--r--sys/kern/kern_malloc.c39
1 files changed, 21 insertions, 18 deletions
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index 963cf09..00df9dd 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -427,8 +427,12 @@ malloc(unsigned long size, struct malloc_type *mtp, int flags)
("malloc(M_WAITOK) in interrupt context"));
#ifdef DEBUG_MEMGUARD
- if (memguard_cmp(mtp))
- return memguard_alloc(size, flags);
+ if (memguard_cmp(mtp, size)) {
+ va = memguard_alloc(size, flags);
+ if (va != NULL)
+ return (va);
+ /* This is unfortunate but should not be fatal. */
+ }
#endif
#ifdef DEBUG_REDZONE
@@ -493,7 +497,7 @@ free(void *addr, struct malloc_type *mtp)
return;
#ifdef DEBUG_MEMGUARD
- if (memguard_cmp(mtp)) {
+ if (is_memguard_addr(addr)) {
memguard_free(addr);
return;
}
@@ -562,10 +566,11 @@ realloc(void *addr, unsigned long size, struct malloc_type *mtp, int flags)
*/
#ifdef DEBUG_MEMGUARD
-if (memguard_cmp(mtp)) {
- slab = NULL;
- alloc = size;
-} else {
+ if (is_memguard_addr(addr)) {
+ slab = NULL;
+ alloc = size;
+ goto remalloc;
+ }
#endif
#ifdef DEBUG_REDZONE
@@ -591,7 +596,7 @@ if (memguard_cmp(mtp)) {
#endif /* !DEBUG_REDZONE */
#ifdef DEBUG_MEMGUARD
-}
+remalloc:
#endif
/* Allocate a new, bigger (or smaller) block */
@@ -625,7 +630,7 @@ static void
kmeminit(void *dummy)
{
uint8_t indx;
- u_long mem_size;
+ u_long mem_size, tmp;
int i;
mtx_init(&malloc_mtx, "malloc", NULL, MTX_DEF);
@@ -685,8 +690,13 @@ kmeminit(void *dummy)
*/
init_param3(vm_kmem_size / PAGE_SIZE);
+#ifdef DEBUG_MEMGUARD
+ tmp = memguard_fudge(vm_kmem_size, vm_kmem_size_max);
+#else
+ tmp = vm_kmem_size;
+#endif
kmem_map = kmem_suballoc(kernel_map, &kmembase, &kmemlimit,
- vm_kmem_size, TRUE);
+ tmp, TRUE);
kmem_map->system_map = 1;
#ifdef DEBUG_MEMGUARD
@@ -695,14 +705,7 @@ kmeminit(void *dummy)
* replacement allocator used for detecting tamper-after-free
* scenarios as they occur. It is only used for debugging.
*/
- vm_memguard_divisor = 10;
- TUNABLE_INT_FETCH("vm.memguard.divisor", &vm_memguard_divisor);
-
- /* Pick a conservative value if provided value sucks. */
- if ((vm_memguard_divisor <= 0) ||
- ((vm_kmem_size / vm_memguard_divisor) == 0))
- vm_memguard_divisor = 10;
- memguard_init(kmem_map, vm_kmem_size / vm_memguard_divisor);
+ memguard_init(kmem_map);
#endif
uma_startup2();
OpenPOWER on IntegriCloud