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?)" : "");

Reply via email to