On Tue, Sep 29, 2020 at 08:17:54AM +0200, Otto Moerbeek wrote:
> 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.
Any takers apart from tb@ who tested this earlier?
-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?)" : "");
>