On Wed, Oct 17, 2018 at 04:20:18PM +0200, ck...@pestilenz.org wrote:

> >Synopsis:    fmt(1) causes a trap with activated canaries
> >Category:    system
> >Environment:
>       System      : OpenBSD 6.3
>       Details     : OpenBSD 6.3 (GENERIC) #11: Thu Sep 20 15:53:36 CEST 2018
>                        
> r...@syspatch-63-amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC
> 
>       Architecture: OpenBSD.amd64
>       Machine     : amd64
> >Description:
>         This problem has been found while using fmt(1) to reflow
>         mail in mutt. The test case has been found with afl.  Without
>         any malloc.conf settings the free() call in fmt will not
>         cause a trap (of course). But with an activated canary in
>         malloc.conf it causes a trap.  Other inputs may trigger
>         similar errors, this has been the smallest one I could find.
>         This has been tested on 6.3 and a -current snapshot of sep
>         30th.
> >How-To-Repeat:
>       Create a file t:
> 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
> 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
>         (100 '0's on one line followed by 101 '0's on the second)
> 
>         Set the C flag on malloc.conf.
>       ls -l /etc/malloc.conf
>       lrwxr-xr-x  1 root  wheel  1 Oct 17 15:42 /etc/malloc.conf -> C
> 
>         Run 'fmt t'
>       fmt(39666) in realloc(): chunk canary corrupted 0xfc10db83780 0x64@0x64
>       Abort trap
> 
> >Fix:
>         I have not worked on a fix yet, since I don't know whether
>         this is a known problem.  The error seems to lie in the
>         canary code, but I am not familiar with it.

The bug is in fmt. If len == length the buf[len] = '\0' statement is
an overflow, which happens if the line is exactly 100 chars long.

This fixes it,

        -Otto

Index: fmt.c
===================================================================
RCS file: /cvs/src/usr.bin/fmt/fmt.c,v
retrieving revision 1.38
diff -u -p -r1.38 fmt.c
--- fmt.c       20 Feb 2017 15:48:00 -0000      1.38
+++ fmt.c       17 Oct 2018 16:45:57 -0000
@@ -699,6 +699,10 @@ get_line(FILE *stream)
        }
        while (len > 0 && isspace((unsigned char)buf[len-1]))
                --len;
+       if (len >= length) {
+               length *= 2;
+               buf = xrealloc(buf, length);
+       }
        buf[len] = '\0';
        return (len > 0 || ch != EOF) ? buf : NULL;
 }

Reply via email to