diff options
author | 2013-03-15 19:10:43 +0000 | |
---|---|---|
committer | 2013-03-15 19:10:43 +0000 | |
commit | ad889e45133558cffa08c32516de9af5676b9ba7 (patch) | |
tree | 59330bc6acc6c0a62bdf363c5fc72f593ca0d191 /sys/kern/kern_malloc.c | |
parent | threadsafe random(). (diff) | |
download | wireguard-openbsd-ad889e45133558cffa08c32516de9af5676b9ba7.tar.xz wireguard-openbsd-ad889e45133558cffa08c32516de9af5676b9ba7.zip |
factor out the deadbeef code for legibility.
ok deraadt
Diffstat (limited to 'sys/kern/kern_malloc.c')
-rw-r--r-- | sys/kern/kern_malloc.c | 88 |
1 files changed, 51 insertions, 37 deletions
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c index 3a0b89d82f0..542fa76e28d 100644 --- a/sys/kern/kern_malloc.c +++ b/sys/kern/kern_malloc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_malloc.c,v 1.94 2013/02/17 17:39:29 miod Exp $ */ +/* $OpenBSD: kern_malloc.c,v 1.95 2013/03/15 19:10:43 tedu Exp $ */ /* $NetBSD: kern_malloc.c,v 1.15.4.2 1996/06/13 17:10:56 cgd Exp $ */ /* @@ -140,7 +140,41 @@ const long addrmask[] = { 0, #else #define WEIRD_ADDR ((unsigned) 0xdeadbeef) #endif -#define MAX_COPY 32 +#define POISON_SIZE 32 + +static void +poison(void *v, size_t len) +{ + uint32_t *ip = v; + size_t i; + + if (len > POISON_SIZE) + len = POISON_SIZE; + len = len / sizeof(*ip); + for (i = 0; i < len; i++) { + ip[i] = WEIRD_ADDR; + } +} + +static size_t +poison_check(void *v, size_t len) +{ + + uint32_t *ip = v; + size_t i; + + if (len > POISON_SIZE) + len = POISON_SIZE; + len = len / sizeof(*ip); + for (i = 0; i < len; i++) { + if (ip[i] != WEIRD_ADDR) { + return i; + } + } + return -1; +} + + /* * Normally the freelist structure is used only to hold the list pointer @@ -180,8 +214,8 @@ malloc(unsigned long size, int type, int flags) int s; caddr_t va, cp, savedlist; #ifdef DIAGNOSTIC - int32_t *end, *lp; - int copysize, freshalloc; + size_t pidx; + int freshalloc; char *savedtype; #endif #ifdef KMEMSTATS @@ -232,14 +266,11 @@ malloc(unsigned long size, int type, int flags) } ksp->ks_size |= 1 << indx; #endif -#ifdef DIAGNOSTIC - copysize = 1 << indx < MAX_COPY ? 1 << indx : MAX_COPY; -#endif + if (size > MAXALLOCSAVE) + allocsize = round_page(size); + else + allocsize = 1 << indx; if (kbp->kb_next == NULL) { - if (size > MAXALLOCSAVE) - allocsize = round_page(size); - else - allocsize = 1 << indx; npg = atop(round_page(allocsize)); va = (caddr_t)uvm_km_kmemalloc_pla(kmem_map, NULL, (vsize_t)ptoa(npg), 0, @@ -294,9 +325,7 @@ malloc(unsigned long size, int type, int flags) * Copy in known text to detect modification * after freeing. */ - end = (int32_t *)&cp[copysize]; - for (lp = (int32_t *)cp; lp < end; lp++) - *lp = WEIRD_ADDR; + poison(cp, allocsize); freep->type = M_FREE; #endif /* DIAGNOSTIC */ if (cp <= va) @@ -338,29 +367,17 @@ malloc(unsigned long size, int type, int flags) } /* Fill the fields that we've used with WEIRD_ADDR */ -#if BYTE_ORDER == BIG_ENDIAN - freep->type = WEIRD_ADDR >> 16; -#endif -#if BYTE_ORDER == LITTLE_ENDIAN - freep->type = (short)WEIRD_ADDR; -#endif - end = (int32_t *)&freep->next + - (sizeof(freep->next) / sizeof(int32_t)); - for (lp = (int32_t *)&freep->next; lp < end; lp++) - *lp = WEIRD_ADDR; + poison(freep, sizeof(*freep)); /* and check that the data hasn't been modified. */ if (freshalloc == 0) { - end = (int32_t *)&va[copysize]; - for (lp = (int32_t *)va; lp < end; lp++) { - if (*lp == WEIRD_ADDR) - continue; + if ((pidx = poison_check(va, allocsize)) != -1) { printf("%s %zd of object %p size 0x%lx %s %s" " (0x%x != 0x%x)\n", "Data modified on freelist: word", - lp - (int32_t *)va, va, size, - "previous type", savedtype, *lp, WEIRD_ADDR); - break; + pidx, va, size, "previous type", + savedtype, ((int32_t*)va)[pidx], WEIRD_ADDR); + panic("boom"); } } @@ -404,8 +421,7 @@ free(void *addr, int type) int s; #ifdef DIAGNOSTIC caddr_t cp; - int32_t *end, *lp; - long alloc, copysize; + long alloc; #endif #ifdef KMEMSTATS struct kmemstats *ksp = &kmemstats[type]; @@ -476,10 +492,8 @@ free(void *addr, int type) * so we can list likely culprit if modification is detected * when the object is reallocated. */ - copysize = size < MAX_COPY ? size : MAX_COPY; - end = (int32_t *)&((caddr_t)addr)[copysize]; - for (lp = (int32_t *)addr; lp < end; lp++) - *lp = WEIRD_ADDR; + poison(addr, size); + freep->type = type; #endif /* DIAGNOSTIC */ #ifdef KMEMSTATS |