Hi, until now, canary bytes (used by the C olption) were the same as the bytes used to junk (0xfd). This means that certain overwrites are not detected, like setting the high bit.
This makes the byte value used to write canaries random. I do not want to complicate the code to handle all combinatuon of F and C, so 0xfd is still acepted as a canary byte. Please test with all your favourite combinations of malloc flags. -Otto Index: malloc.c =================================================================== RCS file: /cvs/src/lib/libc/stdlib/malloc.c,v retrieving revision 1.263 diff -u -p -r1.263 malloc.c --- malloc.c 6 Sep 2020 06:41:03 -0000 1.263 +++ malloc.c 10 Sep 2020 10:53:18 -0000 @@ -193,7 +193,7 @@ struct malloc_readonly { int def_malloc_junk; /* junk fill? */ int malloc_realloc; /* always realloc? */ int malloc_xmalloc; /* xmalloc behaviour? */ - int chunk_canaries; /* use canaries after chunks? */ + u_int chunk_canaries; /* use canaries after chunks? */ int internal_funcs; /* use better recallocarray/freezero? */ u_int def_malloc_cache; /* free pages we cache */ size_t malloc_guard; /* use guard pages after allocations? */ @@ -468,6 +468,11 @@ omalloc_init(void) while ((mopts.malloc_canary = arc4random()) == 0) ; + if (mopts.chunk_canaries) + do { + mopts.chunk_canaries = arc4random(); + } while ((u_char)mopts.chunk_canaries == 0 || + (u_char)mopts.chunk_canaries == SOME_FREEJUNK); } static void @@ -938,7 +943,7 @@ fill_canary(char *ptr, size_t sz, size_t if (check_sz > CHUNK_CHECK_LENGTH) check_sz = CHUNK_CHECK_LENGTH; - memset(ptr + sz, SOME_JUNK, check_sz); + memset(ptr + sz, mopts.chunk_canaries, check_sz); } /* @@ -1039,7 +1044,7 @@ validate_canary(struct dir_info *d, u_ch q = p + check_sz; while (p < q) { - if (*p != SOME_JUNK) { + if (*p != (u_char)mopts.chunk_canaries && *p != SOME_JUNK) { wrterror(d, "chunk canary corrupted %p %#tx@%#zx%s", ptr, p - ptr, sz, *p == SOME_FREEJUNK ? " (double free?)" : "");