\chapter{Fuzzing with afl-fuzz} %HEVEA\cutname{afl-fuzz.html} \section{s:afl-overview}{Overview} American fuzzy lop (``afl-fuzz'') is a {\em fuzzer}, a tool for testing software by providing randomly-generated inputs, searching for those inputs which cause the program to crash. Unlike most fuzzers, afl-fuzz observes the internal behaviour of the program being tested, and adjusts the test cases it generates to trigger unexplored execution paths. As a result, test cases generated by afl-fuzz cover more of the possible behaviours of the tested program than other fuzzers. This requires that programs to be tested are instrumented to communicate with afl-fuzz. The native-code compiler ``ocamlopt'' can generate such instrumentation, allowing afl-fuzz to be used against programs written in OCaml. For more information on afl-fuzz, see the website at \ifouthtml \ahref{http://lcamtuf.coredump.cx/afl/}{http://lcamtuf.coredump.cx/afl/}. \else {\tt http://lcamtuf.coredump.cx/afl/} \fi \section{s:afl-generate}{Generating instrumentation} The instrumentation that afl-fuzz requires is not generated by default, and must be explicitly enabled, by passing the {\tt -afl-instrument} option to {\tt ocamlopt}. To fuzz a large system without modifying build tools, OCaml's {\tt configure} script also accepts the {\tt afl-instrument} option. If OCaml is configured with {\tt afl-instrument}, then all programs compiled by {\tt ocamlopt} will be instrumented. \subsection{ss:afl-advanced}{Advanced options} In rare cases, it is useful to control the amount of instrumentation generated. By passing the {\tt -afl-inst-ratio N} argument to {\tt ocamlopt} with {\tt N} less than 100, instrumentation can be generated for only N\% of branches. (See the afl-fuzz documentation on the parameter {\tt AFL\_INST\_RATIO} for the precise effect of this). \section{s:afl-example}{Example} As an example, we fuzz-test the following program, {\tt readline.ml}: \begin{verbatim} let _ = let s = read_line () in match Array.to_list (Array.init (String.length s) (String.get s)) with ['s'; 'e'; 'c'; 'r'; 'e'; 't'; ' '; 'c'; 'o'; 'd'; 'e'] -> failwith "uh oh" | _ -> () \end{verbatim} There is a single input (the string ``secret code'') which causes this program to crash, but finding it by blind random search is infeasible. Instead, we compile with afl-fuzz instrumentation enabled: \begin{verbatim} ocamlopt -afl-instrument readline.ml -o readline \end{verbatim} Next, we run the program under afl-fuzz: \begin{verbatim} mkdir input echo asdf > input/testcase mkdir output afl-fuzz -m none -i input -o output ./readline \end{verbatim} By inspecting instrumentation output, the fuzzer finds the crashing input quickly. Note: To fuzz-test an OCaml program with afl-fuzz, passing the option {\tt -m none} is required to disable afl-fuzz's default 50MB virtual memory limit.