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

Reply via email to