Hi, chunk pages do not need to be junked, all allocated chunks are already junked on free. Same hold for a few error paths.
Also, for freezero(), only clear the size as reqeusted instead of the whole allocation. Please review/test, -Otto Index: malloc.c =================================================================== RCS file: /cvs/src/lib/libc/stdlib/malloc.c,v retrieving revision 1.241 diff -u -p -r1.241 malloc.c --- malloc.c 18 Jan 2018 20:06:16 -0000 1.241 +++ malloc.c 20 Jan 2018 20:46:57 -0000 @@ -633,7 +633,7 @@ delete(struct dir_info *d, struct region * cache are in MALLOC_PAGESIZE units. */ static void -unmap(struct dir_info *d, void *p, size_t sz, int clear) +unmap(struct dir_info *d, void *p, size_t sz, size_t clear, int junk) { size_t psz = sz >> MALLOC_PAGESHIFT; size_t rsz; @@ -650,7 +650,7 @@ unmap(struct dir_info *d, void *p, size_ * to unmap is larger than the cache size or we're clearing and the * cache is full, just munmap */ - if (psz > mopts.malloc_cache || (clear && rsz == 0)) { + if (psz > mopts.malloc_cache || (clear > 0 && rsz == 0)) { i = munmap(p, sz); if (i) wrterror(d, "munmap %p", p); @@ -686,11 +686,10 @@ unmap(struct dir_info *d, void *p, size_ for (i = 0; ; i++) { r = &d->free_regions[(i + offset) & mask]; if (r->p == NULL) { - if (clear) - memset(p, 0, sz - mopts.malloc_guard); - if (mopts.malloc_junk && !mopts.malloc_freeunmap) { - size_t amt = mopts.malloc_junk == 1 ? - MALLOC_MAXCHUNK : sz; + if (clear > 0) + memset(p, 0, clear); + if (junk && !mopts.malloc_freeunmap) { + size_t amt = junk == 1 ? MALLOC_MAXCHUNK : sz; memset(p, SOME_FREEJUNK, amt); } if (mopts.malloc_freeunmap) @@ -888,7 +887,7 @@ omalloc_make_chunks(struct dir_info *d, return bp; err: - unmap(d, pp, MALLOC_PAGESIZE, 0); + unmap(d, pp, MALLOC_PAGESIZE, 0, mopts.malloc_junk); return NULL; } @@ -1087,7 +1086,7 @@ free_bytes(struct dir_info *d, struct re if (info->size == 0 && !mopts.malloc_freeunmap) mprotect(info->page, MALLOC_PAGESIZE, PROT_READ | PROT_WRITE); - unmap(d, info->page, MALLOC_PAGESIZE, 0); + unmap(d, info->page, MALLOC_PAGESIZE, 0, 0); delete(d, r); if (info->size != 0) @@ -1118,7 +1117,7 @@ omalloc(struct dir_info *pool, size_t sz return NULL; } if (insert(pool, p, sz, f)) { - unmap(pool, p, psz, 0); + unmap(pool, p, psz, 0, 0); errno = ENOMEM; return NULL; } @@ -1309,8 +1308,7 @@ ofree(struct dir_info *argpool, void *p, uint32_t chunknum = find_chunknum(pool, info, p, 0); - if (info->bits[info->offset + chunknum] < - argsz) + if (info->bits[info->offset + chunknum] < argsz) wrterror(pool, "recorded size %hu" " < %zu", info->bits[info->offset + chunknum], @@ -1350,7 +1348,8 @@ ofree(struct dir_info *argpool, void *p, } STATS_SUB(pool->malloc_guarded, mopts.malloc_guard); } - unmap(pool, p, PAGEROUND(sz), clear); + unmap(pool, p, PAGEROUND(sz), clear ? argsz : 0, + mopts.malloc_junk); delete(pool, r); } else { /* Validate and optionally canary check */ @@ -1376,8 +1375,8 @@ ofree(struct dir_info *argpool, void *p, pool->delayed_chunks[i] = tmp; if (mopts.malloc_junk) validate_junk(pool, p); - } else if (sz > 0) - memset(p, 0, sz); + } else if (argsz > 0) + memset(p, 0, argsz); if (p != NULL) { r = find(pool, p); if (r == NULL) @@ -1575,7 +1574,8 @@ gotit: PROT_NONE)) wrterror(pool, "mprotect"); } - unmap(pool, (char *)r->p + rnewsz, roldsz - rnewsz, 0); + unmap(pool, (char *)r->p + rnewsz, roldsz - rnewsz, 0, + mopts.malloc_junk); r->size = gnewsz; if (MALLOC_MOVE_COND(gnewsz)) { void *pp = MALLOC_MOVE(r->p, gnewsz); @@ -1791,7 +1791,7 @@ orecallocarray(struct dir_info *argpool, } else memcpy(newptr, p, newsize); - ofree(pool, p, 1, 0, 0); + ofree(pool, p, 1, 0, oldsize); done: if (argpool != pool) { @@ -1984,7 +1984,7 @@ omemalign(struct dir_info *pool, size_t } if (insert(pool, p, sz, f)) { - unmap(pool, p, psz, 0); + unmap(pool, p, psz, 0, 0); errno = ENOMEM; return NULL; }