summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_malloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_malloc.c')
-rw-r--r--sys/kern/kern_malloc.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index 4b57892e809..0c73763e022 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_malloc.c,v 1.98 2013/03/28 16:41:39 tedu Exp $ */
+/* $OpenBSD: kern_malloc.c,v 1.99 2013/04/06 03:53:25 tedu Exp $ */
/* $NetBSD: kern_malloc.c,v 1.15.4.2 1996/06/13 17:10:56 cgd Exp $ */
/*
@@ -120,6 +120,21 @@ char *memall = NULL;
struct rwlock sysctl_kmemlock = RWLOCK_INITIALIZER("sysctlklk");
#endif
+/*
+ * Normally the freelist structure is used only to hold the list pointer
+ * for free objects. However, when running with diagnostics, the first
+ * 8 bytes of the structure is unused except for diagnostic information,
+ * and the free list pointer is at offset 8 in the structure. Since the
+ * first 8 bytes is the portion of the structure most often modified, this
+ * helps to detect memory reuse problems and avoid free list corruption.
+ */
+struct kmem_freelist {
+ int32_t kf_spare0;
+ int16_t kf_type;
+ int16_t kf_spare1;
+ SIMPLEQ_ENTRY(kmem_freelist) kf_flist;
+};
+
#ifdef DIAGNOSTIC
/*
* This structure provides a set of masks to catch unaligned frees.
@@ -131,16 +146,6 @@ const long addrmask[] = { 0,
0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
};
-/*
- * The FREELIST_MARKER is used as known text to copy into free objects so
- * that modifications after frees can be detected.
- */
-#ifdef DEADBEEF0
-#define FREELIST_MARKER ((unsigned) DEADBEEF0)
-#else
-#define FREELIST_MARKER ((unsigned) 0xdeadbeef)
-#endif
-
#endif /* DIAGNOSTIC */
#ifndef SMALL_KERNEL
@@ -413,7 +418,7 @@ free(void *addr, int type)
* Check for multiple frees. Use a quick check to see if
* it looks free before laboriously searching the freelist.
*/
- if (freep->kf_spare0 == FREELIST_MARKER) {
+ if (freep->kf_spare0 == poison_value(freep)) {
struct kmem_freelist *fp;
SIMPLEQ_FOREACH(fp, &kbp->kb_freelist, kf_flist) {
if (addr != fp)
@@ -429,7 +434,7 @@ free(void *addr, int type)
* when the object is reallocated.
*/
poison_mem(addr, size);
- freep->kf_spare0 = FREELIST_MARKER;
+ freep->kf_spare0 = poison_value(freep);
freep->kf_type = type;
#endif /* DIAGNOSTIC */