Fuzzing Terminology with AFL

I wanted to fuzz Terminology for quite a long time. In late August, I found this article about American Fuzzy Lop. All I had to do to have it work with Terminology is to have Terminology take its input stdin (or a file but I chose to read from stdin) instead of a tty.

When epoll is not behaving as I’d like

I did those changes but afl was not happy because Terminology was crashing right-away. I ran my first test-case like that:

    cat afl/in/colors_font | src/bin/terminology

and it worked like a charm. A window appeared and disappeared with no error message in the logs. The return code was 0. Nothing misbehaving here, but only when ran with afl.

Terminology uses epoll to know when there is some new data to read from stdin. Due to the way afl works, stdin is a file descriptor to a regular file (set to stdin after fork() before exec() using dup2()). When adding stdin to epoll_ctl(), it replied EBADF saying that stdin is not a valid file descriptor (to epoll) since epoll can not be used to poll regular files.

I did patch afl to make stdin behave like a pipe for the test application and then it worked (almost) great.

afl did find bugs

afl did find a bug in Terminology that resulted in this commit.

It also did find an other bug, but outside Terminology: in Enlightenment! afl kept on spawning Terminology and thus kept on creating and closing windows. At some point Enlightenment would crash. This led to T2803 that is now fixed thanks to zmike.

tyfuzz

Because Terminology had to create windows all the time and initialize a bunch of stuff, it was slow to actually do the fuzzing. I wrote a small piece of code called tyfuzz to only test the relevant parts: the parsing of the escape codes. I has been running in afl for 2 days but it did not yield any crash so far.

How to run it?

Everything is currently on git. One need to compile Terminology with the afl compiler companion tool and activate fuzzing.

CC=afl-gcc ./autogen.sh --enable-fuzzing && make

Terminology produced that way won’t be usable outside afl.

afl-fuzz -m none -i afl/in -o afl/out -- src/bin/terminology -s
or
afl-fuzz -m none -i afl/in -o afl/out -- src/bin/tyfuzz -s