Add additional segment handling Fix bug in split_free_chunk when remainder is too small
diff --git a/preload.c b/preload.c index 841ddbb..19bdd70 100644 --- a/preload.c +++ b/preload.c
@@ -213,12 +213,11 @@ if (m.seg == NULL) { m.seg = seg; } else { - for (sp = m.seg; sp->next == NULL; sp = sp->next) + for (sp = m.seg; sp->next != NULL; sp = sp->next) ; sp->next = seg; } c = next_chunk(c); - printf("NEXT CHUNK %p\n", c); c->head = (size_t)(((char *)p + SEG_SIZE) - (char *)c) | PINUSE_BIT; c->prev_foot = ssize; DEBUG("next chunk at 0x%p, head=%x, prev=%x\n", c, chunk_size(c), c->prev_foot); @@ -236,7 +235,6 @@ m.free.fd = &m.free; m.free.bk = &m.free; m.seg = NULL; - alloc_segment(); } static struct malloc_chunk *find_free(size_t size) @@ -258,10 +256,13 @@ struct malloc_chunk *new_c, *n; size_t csize = chunk_size(c); - if (csize == size) { + if (csize - size < pad_request(1)) { /* nothing to split, just give everything up */ unlink_free_chunk(c); c->head |= CINUSE_BIT; + new_c = next_chunk(c); + if (new_c) + new_c->head |= PINUSE_BIT; return; } @@ -289,9 +290,9 @@ size = pad_request(size); c = find_free(size); if (c == NULL) { - printf("failed to find free\n"); - /* FIXME ADD MORE */ - return NULL; + alloc_segment(); + c = find_free(size); + ASSERT(c != NULL); } DEBUG("found chunk 0x%p\n", c); @@ -304,7 +305,7 @@ void *ret = NULL; if (size < SEG_SIZE) ret = dlmalloc(size); - DEBUG("in crypto malloc from %s:%d =%p\n", file, line, ret); + DEBUG("in crypto malloc from %s:%d size=%x ret=%p\n", file, line, size, ret); show_segment(); return ret; } @@ -313,7 +314,7 @@ { struct malloc_chunk *c, *n; - DEBUG("in crypto free from %s:%d\n", file, line); + DEBUG("in crypto free from %s:%d; ptr=%p\n", file, line, ptr); if (ptr == NULL) return; @@ -323,7 +324,7 @@ n = next_chunk(c); DEBUG("free c=%p, n=%p, next_in_use=%d, prev_in_use=%d\n", - c,n,in_use(n),prev_in_use(c)); + c,n,n && in_use(n),prev_in_use(c)); /* now check for consolidation with previous */ if (!prev_in_use(c)) {
diff --git a/preload_test.c b/preload_test.c index 8d13215..8923dd4 100644 --- a/preload_test.c +++ b/preload_test.c
@@ -15,7 +15,7 @@ int main(int argc, const char *argv[]) { - void *mem[7]; + void *mem[50]; int i; printf("\nAlloc array\n\n"); @@ -62,6 +62,39 @@ OPENSSL_free(mem[i]); + printf("\nForce Allocation across the segment boundary\n\n"); + mem[0] = OPENSSL_malloc(0x1ff000); + + for (i = 1; i < ARRAY_SIZE(mem); i++) + mem[i] = myalloc(); + + printf("\nFree *2\n\n"); + for (i = 0; i < ARRAY_SIZE(mem); i += 2) + OPENSSL_free(mem[i]); + printf("\nFree holes\n\n"); + for (i = 1; i < ARRAY_SIZE(mem); i += 2) + OPENSSL_free(mem[i]); + + printf("\nFail oversize allocation\n\n"); + mem[0] = OPENSSL_malloc(2*1024*1024); + if (mem[0] != NULL) + printf("FAILED\n"); + + printf("\n100 Random allocations and frees\n\n"); + + memset(mem, 0, sizeof(mem)); + + for (i = 0; i < 300; i++) { + int j = random()%ARRAY_SIZE(mem); + if (mem[j]) { + OPENSSL_free(mem[j]); + mem[j] = NULL; + } else { + mem[j] = myalloc(); + } + } + for (i = 0; i < ARRAY_SIZE(mem); i++) + OPENSSL_free(mem[i]); exit(0); }