On Thu, Mar 30, 2023 at 04:53:05PM +0200, Otto Moerbeek wrote: > Hi, > > this came up after a remark by tb@; it does a more thorough check of > the chunks in the delay list if malloc option F (which is included in > S). > > Catches way more use-after-free's as otherwise we'll have to wait > until a chunk is actively re-used. With the new bucket code that might > take longer (or not happen at all because the program terminates). The > catch also happens closer (in time) to the actual write after free. > That might help finding the root cause.
Thank you. This works indeed a lot better in my testing. ok tb > > -Otto > > Index: stdlib/malloc.3 > =================================================================== > RCS file: /home/cvs/src/lib/libc/stdlib/malloc.3,v > retrieving revision 1.129 > diff -u -p -r1.129 malloc.3 > --- stdlib/malloc.3 31 Mar 2022 17:27:16 -0000 1.129 > +++ stdlib/malloc.3 30 Mar 2023 14:47:19 -0000 > @@ -293,7 +293,8 @@ order to have any effect. > .It Cm F > .Dq Freecheck . > Enable more extensive double free and use after free detection. > -All chunks in the delayed free list will be checked for double frees. > +All chunks in the delayed free list will be checked for double frees and > +write after frees. > Unused pages on the freelist are read and write protected to > cause a segmentation fault upon access. > .It Cm G > Index: stdlib/malloc.c > =================================================================== > RCS file: /home/cvs/src/lib/libc/stdlib/malloc.c,v > retrieving revision 1.278 > diff -u -p -r1.278 malloc.c > --- stdlib/malloc.c 25 Mar 2023 15:22:06 -0000 1.278 > +++ stdlib/malloc.c 30 Mar 2023 14:47:19 -0000 > @@ -1554,11 +1554,25 @@ ofree(struct dir_info **argpool, void *p > find_chunknum(pool, info, p, mopts.chunk_canaries); > > if (mopts.malloc_freecheck) { > - for (i = 0; i <= MALLOC_DELAYED_CHUNK_MASK; i++) > - if (p == pool->delayed_chunks[i]) > + for (i = 0; i <= MALLOC_DELAYED_CHUNK_MASK; i++) { > + tmp = pool->delayed_chunks[i]; > + if (tmp == p) > wrterror(pool, > "double free %p", p); > + if (tmp != NULL) { > + size_t tmpsz; > + > + r = find(pool, tmp); > + if (r == NULL) > + wrterror(pool, > + "bogus pointer (" > + "double free?) %p", tmp); > + REALSIZE(tmpsz, r); > + validate_junk(pool, tmp, tmpsz); > + } > + } > } > + > if (clear && argsz > 0) > explicit_bzero(p, argsz); > junk_free(pool->malloc_junk, p, sz); > @@ -1574,8 +1588,10 @@ ofree(struct dir_info **argpool, void *p > if (r == NULL) > wrterror(pool, > "bogus pointer (double free?) %p", p); > - REALSIZE(sz, r); > - validate_junk(pool, p, sz); > + if (!mopts.malloc_freecheck) { > + REALSIZE(sz, r); > + validate_junk(pool, p, sz); > + } > free_bytes(pool, r, p); > } > } >