summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThierry Deval <tdeval@cvs.openbsd.org>2001-12-05 22:54:02 +0000
committerThierry Deval <tdeval@cvs.openbsd.org>2001-12-05 22:54:02 +0000
commitf30659df398c3a0602cb4daeb0b363a27d76a1d4 (patch)
tree1faea888c688a17dddeb897ea4db160c3689b5bb
parentc2f700f3391d2cdd7b5a68ad5053104f2245d209 (diff)
correct an alignment mis-conception for malloc(0) returned regions.
OK deraadt@
-rw-r--r--lib/libc/stdlib/malloc.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c
index 7c98beed9d5..2234bd64a8e 100644
--- a/lib/libc/stdlib/malloc.c
+++ b/lib/libc/stdlib/malloc.c
@@ -8,7 +8,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: malloc.c,v 1.44 2001/11/01 07:00:51 mickey Exp $";
+static char rcsid[] = "$OpenBSD: malloc.c,v 1.45 2001/12/05 22:54:01 tdeval Exp $";
#endif /* LIBC_SCCS and not lint */
/*
@@ -726,19 +726,28 @@ malloc_make_chunks(bits)
}
}
- bp->size = (1UL<<bits);
- bp->shift = bits;
- bp->total = bp->free = malloc_pagesize >> bits;
- bp->page = pp;
-
/* memory protect the page allocated in the malloc(0) case */
if (bits == 0) {
+
+ bp->size = 0;
+ bp->shift = 1;
+ i = malloc_minsize-1;
+ while (i >>= 1)
+ bp->shift++;
+ bp->total = bp->free = malloc_pagesize >> bp->shift;
+ bp->page = pp;
+
k = mprotect(pp, malloc_pagesize, PROT_NONE);
if (k < 0) {
ifree(pp);
ifree(bp);
return 0;
}
+ } else {
+ bp->size = (1UL<<bits);
+ bp->shift = bits;
+ bp->total = bp->free = malloc_pagesize >> bits;
+ bp->page = pp;
}
/* set all valid bits in the bitmap */
@@ -831,7 +840,7 @@ malloc_bytes(size)
k += (lp-bp->bits)*MALLOC_BITS;
k <<= bp->shift;
- if (malloc_junk && bp->shift != 0)
+ if (malloc_junk && bp->size != 0)
memset((char *)bp->page + k, SOME_JUNK, bp->size);
return (u_char *)bp->page + k;
@@ -924,7 +933,7 @@ irealloc(ptr, size)
} else if (*mp >= MALLOC_MAGIC) { /* Chunk allocation */
/* Check the pointer for sane values */
- if (((u_long)ptr & ((*mp)->size-1))) {
+ if ((u_long)ptr & ((1UL<<((*mp)->shift))-1)) {
wrtwarning("modified (chunk-) pointer.\n");
return 0;
}
@@ -957,7 +966,7 @@ irealloc(ptr, size)
if (p) {
/* copy the lesser of the two sizes, and free the old one */
/* Don't move from/to 0 sized region !!! */
- if (osize != 1 && size != 0) {
+ if (osize != 0 && size != 0) {
if (osize < size)
memcpy(p, ptr, osize);
else
@@ -1121,7 +1130,7 @@ free_bytes(ptr, index, info)
/* Find the chunk number on the page */
i = ((u_long)ptr & malloc_pagemask) >> info->shift;
- if (((u_long)ptr & (info->size-1))) {
+ if ((u_long)ptr & ((1UL<<(info->shift))-1)) {
wrtwarning("modified (chunk-) pointer.\n");
return;
}
@@ -1131,19 +1140,21 @@ free_bytes(ptr, index, info)
return;
}
- if (malloc_junk && info->shift != 0)
+ if (malloc_junk && info->size != 0)
memset(ptr, SOME_JUNK, info->size);
info->bits[i/MALLOC_BITS] |= 1UL<<(i%MALLOC_BITS);
info->free++;
- mp = page_dir + info->shift;
+ if (info->size != 0)
+ mp = page_dir + info->shift;
+ else
+ mp = page_dir;
if (info->free == 1) {
/* Page became non-full */
- mp = page_dir + info->shift;
/* Insert in address order */
while (*mp && (*mp)->next && (*mp)->next->page < info->page)
mp = &(*mp)->next;
@@ -1169,7 +1180,7 @@ free_bytes(ptr, index, info)
page_dir[ptr2index(info->page)] = MALLOC_FIRST;
/* If the page was mprotected, unprotect it before releasing it */
- if (info->shift == 0) {
+ if (info->size == 0) {
mprotect(info->page, malloc_pagesize, PROT_READ|PROT_WRITE);
/* Do we have to care if mprotect succeeds here ? */
}