Why Fuzz Testing?
Unit and integration tests are essential parts of the software development process. However, they have several limitations:
- They need to be written manually by the developer and consequently cost time
- They are based on predefined inputs and expected outputs and are not designed to find unknown bugs
- They only execute a limited set of paths in code
- New tests need to be created as soon as new code is added
Fuzzing is an alternative testing technique originated in the 1980s. The basic idea behind fuzzing is simple: provide random input to the program and report if it crashes. If the software does not crash, repeat with new random input. The problem with the random input method is that it can take a very long time to find relevant inputs, making this technique suitable to only the most simple and shallow bugs.
In 2016, american fuzzy lop (AFL) improved fuzzing by considering the coverage, i.e. the share of traversed code paths in the generation of new inputs. AFL and other coverage-based fuzzers could discover far more paths of a program than “dumb” fuzzers.
The next major improvement in the world of fuzzing came in the form of Sanitizers that detect more types of errors than just crashes. The AddressSanitizer, for example, monitors memory access akin to valgrind (but a lot faster), while the ThreadSanitizer watches for race conditions between multiple threads. Using Sanitizers for fuzzing was made even more practical with the advent of libFuzzer, due to smart handling of the large virtual memory requirements of the AddressSanitizer.
In short, the combination of coverage information with sanitizers is what we call modern fuzzing.
Our testing suite simplifies the setup and enables any company to benefit from these modern, sophisticated fuzzing technologies.