summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2013-04-06 03:53:26 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2013-04-06 03:53:26 +0000
commit6b3be54723d261b2fddd4bacfa6476badc72867c (patch)
tree10742f8a0cf13e541cb5d98543205c8f7b8f8c3f
parent16ca2849d4e3c9f56f06c8b54ba43349365b6b3a (diff)
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
-rw-r--r--sys/kern/kern_malloc.c31
-rw-r--r--sys/kern/subr_pool.c31
-rw-r--r--sys/sys/malloc.h21
-rw-r--r--sys/sys/systm.h5
4 files changed, 32 insertions, 56 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);
diff --git a/sys/sys/malloc.h b/sys/sys/malloc.h
index 3ed7fd554bc..375795ca6bb 100644
--- a/sys/sys/malloc.h
+++ b/sys/sys/malloc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: malloc.h,v 1.103 2013/03/26 16:36:01 tedu Exp $ */
+/* $OpenBSD: malloc.h,v 1.104 2013/04/06 03:53:25 tedu Exp $ */
/* $NetBSD: malloc.h,v 1.39 1998/07/12 19:52:01 augustss Exp $ */
/*
@@ -341,20 +341,7 @@ struct kmemusage {
#define ku_freecnt ku_un.freecnt
#define ku_pagecnt ku_un.pagecnt
-/*
- * 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;
-};
+struct kmem_freelist;
/*
* Set of buckets for each size of memory block that is retained
@@ -411,6 +398,10 @@ extern int sysctl_malloc(int *, u_int, void *, size_t *, void *, size_t,
size_t malloc_roundup(size_t);
void malloc_printit(int (*)(const char *, ...));
+void poison_mem(void *, size_t);
+int poison_check(void *, size_t, size_t *, int *);
+int32_t poison_value(void *);
+
#ifdef MALLOC_DEBUG
int debug_malloc(unsigned long, int, int, void **);
int debug_free(void *, int);
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 0d463310f02..a7b039864fa 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: systm.h,v 1.97 2013/04/06 03:44:34 tedu Exp $ */
+/* $OpenBSD: systm.h,v 1.98 2013/04/06 03:53:25 tedu Exp $ */
/* $NetBSD: systm.h,v 1.50 1996/06/09 04:55:09 briggs Exp $ */
/*-
@@ -185,9 +185,6 @@ extern int splassert_ctl;
void assertwaitok(void);
-void poison_mem(void *, size_t);
-int poison_check(void *, size_t, size_t *, int *);
-
void tablefull(const char *);
int kcopy(const void *, void *, size_t)