Configuration and Environment Variables
Relevant source files
The following files were used as context for generating this wiki page: - [include/envs.h](https://github.com/lagraviereScience/AFLplusplus/blob/HEAD/include/envs.h) - [src/afl-fuzz.c](https://github.com/lagraviereScience/AFLplusplus/blob/HEAD/src/afl-fuzz.c) - [src/afl-cc.c](https://github.com/lagraviereScience/AFLplusplus/blob/HEAD/src/afl-cc.c) - [include/config.h](https://github.com/lagraviereScience/AFLplusplus/blob/HEAD/include/config.h) - [src/afl-fuzz-init.c](https://github.com/lagraviereScience/AFLplusplus/blob/HEAD/src/afl-fuzz-init.c) - [src/afl-tmin.c](https://github.com/lagraviereScience/AFLplusplus/blob/HEAD/src/afl-tmin.c) - [src/afl-analyze.c](https://github.com/lagraviereScience/AFLplusplus/blob/HEAD/src/afl-analyze.c) - [common.h](https://github.com/lagraviereScience/AFLplusplus/blob/HEAD/include/common.h)AFL++ provides a highly flexible configuration system that allows users to control nearly every aspect of the fuzzing process. This is achieved through a combination of compile-time macros, command-line arguments, and environment variables. This hierarchy allows for setting project-wide defaults, which can then be overridden for specific fuzzing campaigns or even individual fuzzer instances.
Understanding these configuration options is crucial for tuning AFL++ for optimal performance against different targets. This document details the various configuration methods, key variables, and their order of precedence.
Configuration Hierarchy
AFL++ applies configuration settings in a specific order of precedence, allowing for fine-grained control.
- Command-Line Arguments: The highest precedence. Options passed directly to
afl-fuzz,afl-cc, etc., will always override environment variables and compile-time defaults. - Environment Variables: Used to control a wide range of runtime and compile-time behaviors. They are the most common way to configure a fuzzing run.
- Compile-Time Macros: Defined in
include/config.h, these provide the base default values for the fuzzer. They require recompiling AFL++ to change.
The following diagram illustrates the configuration loading flow for afl-fuzz.
This diagram shows that command-line arguments are processed first, followed by environment variables, all layered on top of the initial compile-time defaults.
Sources: src/afl-fuzz.c:1100-1111, src/afl-fuzz-init.c:30-35
Compile-Time Configuration
These settings are hardcoded in include/config.h and provide the fundamental defaults for the fuzzer's operation. To change them, AFL++ must be recompiled.
| Macro | Default Value | Description |
|---|---|---|
VERSION | "++4.35a" | The version string for AFL++. |
DEFAULT_SHMEM_SIZE | (8 * 1024 * 1024) | Default shared memory map size (8MB). Can be overridden by AFL_MAP_SIZE. |
EXEC_TIMEOUT | 1000U | Default timeout for the fuzzed program in milliseconds. |
MEM_LIMIT | 0U | Default memory limit for the child process in megabytes (0 = disabled). |
MAX_FILE | (1 * 1024 * 1024L) | Maximum size of an input file in bytes (1MB). |
HAVOC_CYCLES | 256U | Baseline number of random tweaks during a single 'havoc' stage. |
MAP_SIZE_POW2 | 16 | The size of the coverage bitmap as a power of 2 (1U << 16 = 65536). |
FORKSRV_FD | 198 | Designated file descriptor for forkserver commands. |
SHM_ENV_VAR | __AFL_SHM_ID | Environment variable used to pass the main shared memory ID to the target. |
CMPLOG_SHM_ENV_VAR | __AFL_CMPLOG_SHM_ID | Environment variable for passing the CmpLog shared memory ID. |
PERSIST_SIG | "##SIG_AFL_PERSISTENT##" | In-code signature to detect persistent mode. |
DEFER_SIG | "##SIG_AFL_DEFER_FORKSRV##" | In-code signature to detect deferred forkserver mode. |
Sources: include/config.h:20-380
Runtime Configuration via Environment Variables
Environment variables are the most common and flexible way to configure AFL++. They are read at startup by tools like afl-fuzz and afl-cc.
Fuzzer Behavior
These variables control the overall behavior and state of the afl-fuzz process.
| Variable | Description |
|---|---|
AFL_AUTORESUME | If set, afl-fuzz will automatically resume a fuzzing session if the output directory (-o) already exists. |
AFL_EXIT_WHEN_DONE | Exit when all inputs in the queue have been fuzzed and no new paths have been found in a full cycle. |
AFL_NO_AFFINITY | Disables binding the fuzzer process to a specific CPU core. |
AFL_TRY_AFFINITY | Tries to bind to a CPU core but does not fail if it's unsuccessful. |
AFL_SKIP_CPUFREQ | Prevents the fuzzer from checking the CPU frequency scaling governor on Linux. |
AFL_NO_UI | Disables the status screen UI. Useful for logging output to a file. |
AFL_PRELOAD | Specifies a shared library to be preloaded (LD_PRELOAD) into the target process. |
AFL_TMPDIR | Specifies a directory for temporary files, like the current input file (.cur_input). Using a RAM disk is recommended. |
AFL_CUSTOM_MUTATOR_LIBRARY | Path to a shared library implementing a custom mutator. |
AFL_PYTHON_MODULE | Specifies a Python module to be used for custom mutations. |
Sources: src/afl-fuzz.c:1100-1500, src/afl-fuzz-init.c:120-150, include/envs.h
Instrumentation and Compiler Control
These variables are primarily used by afl-cc and its variants to control how the target is compiled and instrumented.
This diagram shows the logic within afl-cc for selecting the compiler and instrumentation mode based on environment variables and symlink names.
Sources: src/afl-cc.c:460-750
| Variable | Description |
|---|---|
AFL_CC_COMPILER | Specifies the compiler mode. Can be LTO, LLVM, GCC_PLUGIN, GCC, or CLANG. |
AFL_LLVM_INSTRUMENT | Specifies the LLVM instrumentation mode, e.g., PCGUARD (default), CLASSIC, LTO, CTX, NGRAM-x. |
AFL_USE_ASAN | If set, enables AddressSanitizer (-fsanitize=address). |
AFL_USE_MSAN | If set, enables MemorySanitizer (-fsanitize=memory). |
AFL_USE_UBSAN | If set, enables UndefinedBehaviorSanitizer (-fsanitize=undefined). |
AFL_HARDEN | If set, adds stack protection and other hardening flags during compilation. |
AFL_LLVM_CMPLOG | Enables CmpLog instrumentation to log comparison operands. |
AFL_LLVM_ALLOWLIST / AFL_LLVM_DENYLIST | Path to a file specifying functions or source files to include/exclude from instrumentation. |
AFL_DONT_OPTIMIZE | Disables compiler optimizations (-O0). |
AFL_CC / AFL_CXX | Specifies the path to the real C/C++ compiler to be invoked by afl-cc. |
Sources: src/afl-cc.c:490-850, instrumentation/README.gcc_plugin.md, instrumentation/README.lto.md
Shared Memory and Forkserver
These variables control the communication channel between the fuzzer and the instrumented target.
| Variable | Description |
|---|---|
__AFL_SHM_ID | (Internal) Passes the shared memory ID for the coverage bitmap to the child process. |
AFL_MAP_SIZE | Overrides the DEFAULT_SHMEM_SIZE to set a custom size for the coverage bitmap. |
__AFL_SHM_FUZZ_ID | (Internal) Passes the shared memory ID for testcase data when using shared memory fuzzing instead of file I/O. |
__AFL_SHM_FUZZ_MAP_SIZE | (Internal) Passes the size of the shared memory region for testcase data. |
AFL_DEFER_FORKSRV | Enforces deferred forkserver initialization, even if the DEFER_SIG is not found in the binary. |
AFL_PERSISTENT | Enforces persistent mode, even if the PERSIST_SIG is not found in the binary. |
AFL_NO_FORKSRV | Disables the forkserver and runs the target via execve for each input. This is extremely slow. |
Sources: include/config.h:350-370, src/afl-fuzz-init.c:3000-3020, src/afl-fuzz.c:2600-2650
Command-Line Arguments
Command-line arguments passed to afl-fuzz provide the most direct way to configure a fuzzing run. They have the highest precedence.
Core Options
| Argument | Description |
|---|---|
-i dir | (Required) Specifies the input directory containing seed test cases. Use - to resume a previous session. |
-o dir | (Required) Specifies the output directory where findings will be stored. |
-t msec | Sets the execution timeout in milliseconds. A + suffix enables auto-scaling based on initial seed execution times. |
-m megs | Sets the memory limit for the target process in megabytes. 0 or none disables the limit. |
-f file | Specifies the file path where the target reads its input. If not set, stdin is used. @@ is replaced with the input file path. |
-M id / -S id | Enables distributed fuzzing mode. -M designates a main node, and -S designates a secondary node. |
Fuzzing Strategy Options
| Argument | Description |
|---|---|
-p schedule | Selects the power schedule for prioritizing queue entries. Options include explore (default), fast, exploit, seek, etc. |
-x dict_file | Provides a dictionary of tokens to improve fuzzing of structured data formats. Can be used up to 4 times. |
-c program | Enables and configures CmpLog. Use 0 if the target is already compiled for CmpLog. |
-L minutes | Enables MOpt(imize) mode, a specialized mutation strategy. |
-n | Enables non-instrumented mode for fuzzing black-box binaries without coverage feedback. |
Sources: src/afl-fuzz.c:350-550
Conclusion
AFL++'s configuration system is a powerful tool for adapting the fuzzer to a wide variety of targets and scenarios. By layering compile-time defaults, environment variables, and command-line arguments, it offers both simplicity for new users and deep control for experts. Mastering these options is key to achieving high-performance and effective fuzzing campaigns. The combination of afl-cc environment variables for instrumentation and afl-fuzz variables for runtime behavior allows for a clear separation of concerns between the build and fuzzing stages.