/******************************************************************* * rltest.c Time stamp: <2017-07-08 21:35:38 hackerb9> * * Why does bash, once in a bluemoon, crash in readline? * Hopefully this program + fuzz will help solve the mystery. * * Usage: export ASAN_OPTIONS=handle_segv=0 fuzz -t 5 -n 80 `pwd`/a.out unset ASAN_OPTIONS mv /tmp/a.out.???? crash.me cat crash.me | ./a.out >/dev/null * You may compile with your system's standard libreadline: apt-get install libreadline-dev gcc -g -fsanitize=address rltest.c -l readline * However, I highly recommend compiling libreadline with AddressSanitizer, like so: wget ftp://ftp.gnu.org/gnu/readline/readline-7.0.tar.gz tar -zxvpf readline-7.0.tar.gz mv readline-7.0 readline cd readline CFLAGS="-g -fsanitize=address" ./configure make 2>&1 | tee make.out cd .. gcc -g -fsanitize=address rltest.c -I. \ readline/lib{readline,history}.a -lncurses /*******************************************************************/ #include #include #include #include char *rl_gets(); int main() { char *line; while ((line=rl_gets()) != NULL) { printf("%s\n", line); fflush(stdout); } return 0; } /*****************************************************************************/ /* rl_gets() is a replacement for gets() from the GNU Readline documentation */ /*****************************************************************************/ /* A static variable for holding the line. */ static char *line_read = (char *)NULL; /* Read a string, and return a pointer to it. Returns NULL on EOF. */ char *rl_gets() { /* If the buffer has already been allocated, return the memory to the free pool. */ if (line_read) { free (line_read); line_read = (char *)NULL; } /* Get a line from the user. */ line_read = readline (""); /* If the line has any text in it, save it on the history. */ if (line_read && *line_read) add_history (line_read); return (line_read); } /*****************************************/ /* For a good time, try: */ /* printf '\e\n\eRgy\000' | ./a.out */ /*****************************************/