On Thu, Nov 19, 2015 at 05:52:39PM -0500, Michael McConville wrote:
> I'm already cache-thrashing with all of my side projects, so if anyone's
> interested I'll leave this to them.
>
> A few days ago, I wanted to try American Fuzzy Lop (afl), and bc(1)
> seemed like a good first target: it pretty much just goes from stdin to
> stdout, so there's no code reorganization needed.
>
> For those not familiar, bc compiles its input to dc(1)'s syntax and
> forks to dc.
>
> There are many unique crash paths - 1041 before I killed afl. Most
> center around emit(), which emits a dc instr. Many pass NULL to fputs()
> in emit(). I found at least one (crashes/id:001041*) that
> nondeterministically passes the str pointer 0xdfdfdfdfdfdfdfdf to
> fputs(), which is probably uninitialized or already-freed memory.
> Backtrace below.
>
> malloc.conf(5) may be useful.
>
> Here's the full afl directory:
>
> http://www.sccs.swarthmore.edu/users/16/mmcconv1/bc-afl/
>
>
> Core was generated by `bc'.
> Program terminated with signal SIGBUS, Bus error.
> #0 strlen () at /usr/src/lib/libc/arch/amd64/string/strlen.S:152
> 152 movq (%rax),%rdx /* first data in high bytes */
> (gdb) bt
> #0 strlen () at /usr/src/lib/libc/arch/amd64/string/strlen.S:152
> #1 0x000019f79fa7c43d in *_libc_fputs (s=0xdfdfdfdfdfdfdfdf <error: Cannot
> access memory at address 0xdfdfdfdfdfdfdfdf>, fp=0x1) at
> /usr/src/lib/libc/stdio/fputs.c:50
> #2 0x000019f4ecb0f401 in emit (i=28548786530304) at
> /usr/src/usr.bin/bc/bc.y:810
> #3 yyparse () at /usr/src/usr.bin/bc/bc.y:178
> #4 0x000019f4ecb13f3e in main (argc=1, argv=0x7f7fffffa570) at
> /usr/src/usr.bin/bc/bc.y:1188
This fixes at least one case (id-000141*) and make the printing of
non-ascci chars better
-Otto
Index: bc.y
===================================================================
RCS file: /cvs/src/usr.bin/bc/bc.y,v
retrieving revision 1.48
diff -u -p -r1.48 bc.y
--- bc.y 10 Oct 2015 19:28:54 -0000 1.48
+++ bc.y 20 Nov 2015 10:46:29 -0000
@@ -808,7 +808,7 @@ emit(ssize_t i)
if (instructions[i].index >= 0)
while (instructions[i].index != END_NODE)
emit(instructions[i++].index);
- else
+ else if (instructions[i].index != END_NODE)
fputs(instructions[i].u.cstr, stdout);
}
@@ -951,7 +951,7 @@ yyerror(char *s)
!isprint((unsigned char)yytext[0]))
n = asprintf(&str,
"%s: %s:%d: %s: ascii char 0x%02x unexpected",
- __progname, filename, lineno, s, yytext[0]);
+ __progname, filename, lineno, s, yytext[0] & 0xff);
else
n = asprintf(&str, "%s: %s:%d: %s: %s unexpected",
__progname, filename, lineno, s, yytext);