ok

Otto Moerbeek(o...@drijf.net) on 2015.11.20 14:22:12 +0100:
> On Fri, Nov 20, 2015 at 11:52:16AM +0100, Otto Moerbeek wrote:
> 
> > 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
> > 
> 
> New version, which solves all cases found in crashes, hangs and queue
> above.  The remaining cases were emit going into an infinite recursion
> becuse the tree wasn't a tree but a cyclic graph.
> 
> Regress still succeeds.
> 
>       -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 13:19:07 -0000
> @@ -72,7 +72,7 @@ static void         grow(void);
>  static ssize_t               cs(const char *);
>  static ssize_t               as(const char *);
>  static ssize_t               node(ssize_t, ...);
> -static void          emit(ssize_t);
> +static void          emit(ssize_t, int);
>  static void          emit_macro(int, ssize_t);
>  static void          free_tree(void);
>  static ssize_t               numnode(int);
> @@ -175,7 +175,7 @@ program           : /* empty */
>  
>  input_item   : semicolon_list NEWLINE
>                       {
> -                             emit($1);
> +                             emit($1, 0);
>                               macro_char = reset_macro_char;
>                               putchar('\n');
>                               free_tree();
> @@ -803,12 +803,17 @@ node(ssize_t arg, ...)
>  }
>  
>  static void
> -emit(ssize_t i)
> +emit(ssize_t i, int level)
>  {
> -     if (instructions[i].index >= 0)
> -             while (instructions[i].index != END_NODE)
> -                     emit(instructions[i++].index);
> -     else
> +     if (level > 1000)
> +             errx(1, "internal error: tree level > 1000");
> +     if (instructions[i].index >= 0) {
> +             while (instructions[i].index != END_NODE &&
> +                 instructions[i].index != i)  {
> +                     emit(instructions[i].index, level + 1);
> +                     i++;
> +             }
> +     } else if (instructions[i].index != END_NODE)
>               fputs(instructions[i].u.cstr, stdout);
>  }
>  
> @@ -816,7 +821,7 @@ static void
>  emit_macro(int node, ssize_t code)
>  {
>       putchar('[');
> -     emit(code);
> +     emit(code, 0);
>       printf("]s%s\n", instructions[node].u.cstr);
>       nesting--;
>  }
> @@ -951,7 +956,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);
> 

-- 

Reply via email to