summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authortedu <tedu@openbsd.org>2013-04-06 03:53:25 +0000
committertedu <tedu@openbsd.org>2013-04-06 03:53:25 +0000
commitcbf677f62b0e67b3ff4e432e66cc537ee728d5a3 (patch)
treeba52788b907fe8c93d280fe5cb89eb29c3320a16 /sys/kern
parentremove kern.rthreads (diff)
downloadwireguard-openbsd-cbf677f62b0e67b3ff4e432e66cc537ee728d5a3.tar.xz
wireguard-openbsd-cbf677f62b0e67b3ff4e432e66cc537ee728d5a3.zip
shuffle around some poison code, prototypes, values...
allow some more pool debug code to be enabled if not compiled in bump poison size back up to 64
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_malloc.c31
-rw-r--r--sys/kern/subr_pool.c31
2 files changed, 25 insertions, 37 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 */
diff --git a/sys/kern/subr_pool.c b/sys/kern/subr_pool.c
index 085eab2540d..a22e163d821 100644
--- a/sys/kern/subr_pool.c
+++ b/sys/kern/subr_pool.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_pool.c,v 1.116 2013/03/31 00:03:26 tedu Exp $ */
+/* $OpenBSD: subr_pool.c,v 1.117 2013/04/06 03:53:25 tedu Exp $ */
/* $NetBSD: subr_pool.c,v 1.61 2001/09/26 07:14:56 chs Exp $ */
/*-
@@ -78,19 +78,11 @@ struct pool_item_header {
};
struct pool_item {
-#ifdef DIAGNOSTIC
u_int32_t pi_magic;
-#endif
/* Other entries use only this list entry */
SIMPLEQ_ENTRY(pool_item) pi_list;
};
-#ifdef DEADBEEF1
-#define PI_MAGIC DEADBEEF1
-#else
-#define PI_MAGIC 0xdeafbeef
-#endif
-
#ifdef POOL_DEBUG
int pool_debug = 1;
#else
@@ -463,7 +455,7 @@ pool_alloc_item_header(struct pool *pp, caddr_t storage, int flags)
ph = pool_get(&phpool, (flags & ~(PR_WAITOK | PR_ZERO)) |
PR_NOWAIT);
if (pool_debug && ph != NULL)
- ph->ph_magic = PI_MAGIC;
+ ph->ph_magic = poison_value(ph);
return (ph);
}
@@ -638,11 +630,10 @@ startover:
#endif
#ifdef DIAGNOSTIC
- if (pi->pi_magic != PI_MAGIC)
+ if (pi->pi_magic != poison_value(pi))
panic("pool_do_get(%s): free list modified: "
"page %p; item addr %p; offset 0x%x=0x%x",
pp->pr_wchan, ph->ph_page, pi, 0, pi->pi_magic);
-#ifdef POOL_DEBUG
if (pool_debug && ph->ph_magic) {
size_t pidx;
int pval;
@@ -655,7 +646,6 @@ startover:
pidx * sizeof(int), ip[pidx]);
}
}
-#endif /* POOL_DEBUG */
#endif /* DIAGNOSTIC */
/*
@@ -773,12 +763,10 @@ pool_do_put(struct pool *pp, void *v)
* Return to item list.
*/
#ifdef DIAGNOSTIC
- pi->pi_magic = PI_MAGIC;
-#ifdef POOL_DEBUG
+ pi->pi_magic = poison_value(pi);
if (ph->ph_magic) {
poison_mem(pi + 1, pp->pr_size - sizeof(*pi));
}
-#endif /* POOL_DEBUG */
#endif /* DIAGNOSTIC */
SIMPLEQ_INSERT_HEAD(&ph->ph_itemlist, pi, pi_list);
@@ -922,12 +910,10 @@ pool_prime_page(struct pool *pp, caddr_t storage, struct pool_item_header *ph)
SIMPLEQ_INSERT_TAIL(&ph->ph_itemlist, pi, pi_list);
#ifdef DIAGNOSTIC
- pi->pi_magic = PI_MAGIC;
-#ifdef POOL_DEBUG
+ pi->pi_magic = poison_value(pi);
if (ph->ph_magic) {
poison_mem(pi + 1, pp->pr_size - sizeof(*pi));
}
-#endif /* POOL_DEBUG */
#endif /* DIAGNOSTIC */
cp = (caddr_t)(cp + pp->pr_size);
}
@@ -1143,7 +1129,7 @@ pool_print_pagelist(struct pool_pagelist *pl,
ph->ph_page, ph->ph_nmissing);
#ifdef DIAGNOSTIC
SIMPLEQ_FOREACH(pi, &ph->ph_itemlist, pi_list) {
- if (pi->pi_magic != PI_MAGIC) {
+ if (pi->pi_magic != poison_value(pi)) {
(*pr)("\t\t\titem %p, magic 0x%x\n",
pi, pi->pi_magic);
}
@@ -1298,7 +1284,7 @@ pool_chk_page(struct pool *pp, struct pool_item_header *ph, int expected)
pi = SIMPLEQ_NEXT(pi,pi_list), n++) {
#ifdef DIAGNOSTIC
- if (pi->pi_magic != PI_MAGIC) {
+ if (pi->pi_magic != poison_value(pi)) {
printf("%s: ", label);
printf("pool(%s): free list modified: "
"page %p; item ordinal %d; addr %p "
@@ -1306,7 +1292,6 @@ pool_chk_page(struct pool *pp, struct pool_item_header *ph, int expected)
pp->pr_wchan, ph->ph_page, n, pi, page,
0, pi->pi_magic);
}
-#ifdef POOL_DEBUG
if (pool_debug && ph->ph_magic) {
size_t pidx;
int pval;
@@ -1320,8 +1305,6 @@ pool_chk_page(struct pool *pp, struct pool_item_header *ph, int expected)
page, pidx * sizeof(int), ip[pidx]);
}
}
-
-#endif /* POOL_DEBUG */
#endif /* DIAGNOSTIC */
page =
(caddr_t)((u_long)pi & pp->pr_alloc->pa_pagemask);