OCaml – Fuzzing with afl-fuzz
☰
☰
The OCaml tools
Chapter 24
Fuzzing with afl-fuzz
1
Overview
American fuzzy lop (“afl-fuzz”) is a 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
http://lcamtuf.coredump.cx/afl/.
2
Generating instrumentation
The instrumentation that afl-fuzz requires is not generated by
default, and must be explicitly enabled, by passing the -afl-instrument option to ocamlopt.
To fuzz a large system without modifying build tools, OCaml’s configure script also accepts the afl-instrument option. If
OCaml is configured with afl-instrument, then all programs
compiled by ocamlopt will be instrumented.
2.1
Advanced options
In rare cases, it is useful to control the amount of instrumentation
generated. By passing the -afl-inst-ratio N argument to ocamlopt with N less than 100, instrumentation can be
generated for only N% of branches. (See the afl-fuzz documentation on
the parameter AFL_INST_RATIO for the precise effect of this).
3
Example
As an example, we fuzz-test the following program, readline.ml:
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" | _ -> ()
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:
ocamlopt -afl-instrument readline.ml -o readline
Next, we run the program under afl-fuzz:
mkdir input echo asdf > input/testcase mkdir output afl-fuzz -m none -i input -o output ./readline
By inspecting instrumentation output, the fuzzer finds the crashing input quickly.
Note: To fuzz-test an OCaml program with afl-fuzz, passing the option -m none
is required to disable afl-fuzz’s default 50MB virtual memory limit.
Copyright © 2022 Institut National de
Recherche en Informatique et en Automatique