SUT patching: Overcoming obstacles #
Codebases are often not fuzzing-friendly. This can happen if, for example, the code uses checksums or depends on a global state like a system-time seeded PRNG (i.e., by using
rand
) that causes the code to behave differently for the same input. Refer to
Practical harness rules to learn more about potential problems in your SUT. If you encounter checksums or a global state in your SUT, you may want to apply fuzzing-specific patches to change the behavior of the program during fuzzing, as shown in the following paragraphs.
Typically, C/C++ fuzzers define the macro FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
. This is at least true for libFuzzer, AFL++, LibAFL, and Hongfuzz. If the macro is defined, then the program is being compiled for fuzzing. By using conditional compilation based on that macro, you can overcome obstacles in your code, such as hash checks that often hinder fuzzers at covering deeper code paths. The following figure shows an example.
Note that this means that your SUT is behaving differently during fuzzing and production. Carelessly skipping checks can lead to false positives during fuzzing. For example, skipping the validation of a config file might lead to crashes in the SUT because the code expects config values to have a certain format. If the validation ensures that the config contains non-zero integers, then code called after the validation could misbehave when zero values are encountered. See the following example for an illustration.
A real-world use of this variable occurs in the OpenSSL project, which uses this variable to change how cryptographic algorithms work.