summaryrefslogtreecommitdiff
path: root/sys/kern/kern_malloc.c
diff options
context:
space:
mode:
authorBosko Milekic <bmilekic@FreeBSD.org>2005-01-21 18:09:17 +0000
committerBosko Milekic <bmilekic@FreeBSD.org>2005-01-21 18:09:17 +0000
commite4eb384b477fe50f3c35034be62d8bf7a04e88c9 (patch)
treee3ac68d91ce5b621ef858776db95b6901b4a7e6b /sys/kern/kern_malloc.c
parentdc5ae701946a1c6edf255c5a67ad8537b6be07cc (diff)
Notes
Diffstat (limited to 'sys/kern/kern_malloc.c')
-rw-r--r--sys/kern/kern_malloc.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index e794ec08e7a3..a972854a676b 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -58,6 +58,10 @@ __FBSDID("$FreeBSD$");
#include <vm/uma_int.h>
#include <vm/uma_dbg.h>
+#ifdef DEBUG_MEMGUARD
+#include <vm/memguard.h>
+#endif
+
#if defined(INVARIANTS) && defined(__i386__)
#include <machine/cpu.h>
#endif
@@ -129,6 +133,12 @@ struct {
{0, NULL},
};
+#ifdef DEBUG_MEMGUARD
+u_int vm_memguard_divisor;
+SYSCTL_UINT(_vm, OID_AUTO, memguard_divisor, CTLFLAG_RD, &vm_memguard_divisor,
+ 0, "(kmem_size/memguard_divisor) == memguard submap size");
+#endif
+
u_int vm_kmem_size;
SYSCTL_UINT(_vm, OID_AUTO, kmem_size, CTLFLAG_RD, &vm_kmem_size, 0,
"Size of kernel memory");
@@ -280,6 +290,13 @@ malloc(size, type, flags)
if (flags & M_WAITOK)
KASSERT(curthread->td_intr_nesting_level == 0,
("malloc(M_WAITOK) in interrupt context"));
+
+#ifdef DEBUG_MEMGUARD
+ /* XXX CHANGEME! */
+ if (type == M_SUBPROC)
+ return memguard_alloc(size, flags);
+#endif
+
if (size <= KMEM_ZMAX) {
if (size & KMEM_ZMASK)
size = (size & ~KMEM_ZMASK) + KMEM_ZBASE;
@@ -331,6 +348,14 @@ free(addr, type)
if (addr == NULL)
return;
+#ifdef DEBUG_MEMGUARD
+ /* XXX CHANGEME! */
+ if (type == M_SUBPROC) {
+ memguard_free(addr);
+ return;
+ }
+#endif
+
KASSERT(type->ks_memuse > 0,
("malloc(9)/free(9) confusion.\n%s",
"Probably freeing with wrong type, but maybe not here."));
@@ -389,6 +414,14 @@ realloc(addr, size, type, flags)
if (addr == NULL)
return (malloc(size, type, flags));
+#ifdef DEBUG_MEMGUARD
+/* XXX: CHANGEME! */
+if (type == M_SUBPROC) {
+ slab = NULL;
+ alloc = size;
+} else {
+#endif
+
slab = vtoslab((vm_offset_t)addr & ~(UMA_SLAB_MASK));
/* Sanity check */
@@ -406,6 +439,10 @@ realloc(addr, size, type, flags)
&& (size > (alloc >> REALLOC_FRACTION) || alloc == MINALLOCSIZE))
return (addr);
+#ifdef DEBUG_MEMGUARD
+}
+#endif
+
/* Allocate a new, bigger (or smaller) block */
if ((newaddr = malloc(size, type, flags)) == NULL)
return (NULL);
@@ -502,6 +539,22 @@ kmeminit(dummy)
(vm_offset_t *)&kmemlimit, vm_kmem_size);
kmem_map->system_map = 1;
+#ifdef DEBUG_MEMGUARD
+ /*
+ * Initialize MemGuard if support compiled in. MemGuard is a
+ * 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);
+#endif
+
uma_startup2();
for (i = 0, indx = 0; kmemzones[indx].kz_size != 0; indx++) {