Introduction:
Afdko is a set of tools for building opentype fonts from Postscript and true type fonts. this was previously fuzzed by j00ru of google P0. This library was also used in various adobe products and in windows too. so if you find a issue in it, there are chances that that issue is also present in adobe or windows product as well. although not all the afdko code paths are reachable in windows or adobe. by default this gets compiled in 64 bit. which has its own disadvantages like you can use -m option with AFL which limits the memory for the process. because of this we may miss some unusual crashes with ASAN.
In this post i will cover how to fuzz Afdko using AFL in 32 bit mode.
Downloading the source:
we can simply clone following git repo:
https://github.com/adobe-type-tools/afdko
Compiling:
after you have downloaded the sources, you can go to "afdko/c" directory and run following commands:
CC=afl-gcc ./builalllinux release
this will compile and create various exe files. the file of our interest is "tx" which is present in "afdko/c/tx/exe/linux" folder.
Fuzzing:
after we have instrumented file with afl we can simply run the command:
afl-fuzz -i input -o output -m none -- ./tx -cff @@
this will start the fuzzing. you can also run multiple instances with 1 master and n number of slaves if you have multicore available.
but there are some issue with this:
- no ASAN/MSAN/UBSAN support
- no 32 bit build.
Compiling in 32 bit mode with ASAN/UBSAN
lets compile it with ASAN/MSAN/UBSAN
we need to change couple of files for this and add following to compile it with GCC:
+CFLAGS = $(STD_OPTS) -m32 -g -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer
+LDFLAGS = $(STD_OPTS) -m32 -g -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer
this will make sure that the build is 32 bit and is compiled with ASAN/UBSAN support. as ASAN and MSAN are mutually exclusive, they wont work together. so you can use either one of them depending on your need.
once you compiled the 32 bit build, you can again run afl as below with the corpus you have:
afl-fuzz -i input -o output -m 800 -- ./tx -cff @@
note that -m 800 will set 800MB as memory limit, so if program tries to allocate huge memory like 1GB+ you will get crash. i in fact found couple of such cases where program tries to allocate huge memory because of corrupted headers. this may easily lead to DOS condition.
PS: i have created a patch file for compiling it with 32bit and ASAN/UBSAN. please contact me if you need it. it should be simple though to do at your own. but i did spent lot of time in figuring it out as i am not much in to linux. so happy to help if you need it.
Results:
I fuzzed this for few weeks and found lot of crashes. finally i reported around 8 issues to Afdko which where fixed. although i haven't received any CVEs for them as Afdko issue don't get any CVEs. but it was a good learning experience for me.
Thanks to Afdko team and Adobe PSIRT for their help in getting the reported issues fixed. they have released a new version 3.5.0 which fixes all the issues i have reported to them.
Exercise for the readers:
i have omitted various details from this post, if you are interested in learning more, you can try following:
- figure out which files needs to be modified to compile it in 32 bit with ASAN/MSAN. also check if there is already any build option for this which you can use.
- how to get good corpus so that your fuzzing yields in some good crashes?
- figure out which adobe and windows product may be using this library?
- if you get lot of crashes, how will you triage them?
FUZZING.IN