This framework is designed for testing the Dragonfly server using American Fuzzy Lop (AFL++). Dragonfly is a modern replacement for Redis and Memcached with high performance.
df-afl is a comprehensive tool for fuzz testing Dragonfly that:
- Generates random Redis commands
- Uses AFL++ for systematic testing
- Allows focusing on specific commands
- Uses dictionaries for more effective testing
AFL++ must be installed separately:
# Installation from package manager (Ubuntu/Debian)
sudo apt update
sudo apt install afl++
# Or build from source
git clone https://github.com/AFLplusplus/AFLplusplus
cd AFLplusplus
make distrib
sudo make install
More details:
# Clone the repository
git clone https://github.com/dragonflydb/dragonfly.git
cd dragonfly
# Install dependencies and build (see CONTRIBUTING.md)
./helio/blaze.sh
cd build-dbg
ninja dragonfly
Detailed build instructions: CONTRIBUTING.md
cd dragonfly/tools/replay
go build
This will create the traffic-replay
executable.
For debugging, it's recommended to run Dragonfly with traffic recording enabled:
# Create directory for traffic
mkdir ~/traffic
# Start Dragonfly
./dragonfly --dbfilename= --logtostderr
# In a separate terminal, activate traffic recording
redis-cli DEBUG TRAFFIC ~/traffic/traffic
For optimal AFL++ performance, configure the system:
sudo su -
echo core >/proc/sys/kernel/core_pattern
cd /sys/devices/system/cpu
echo performance | tee cpu*/cpufreq/scaling_governor
# Navigate to the df-afl directory
cd df-afl
# Start fuzzing
./run_afl_fuzzing.sh
If bugs are found, you can replay the traffic:
./traffic-replay -ignore-parse-errors run traffic/traffic*
Controls the ratio between dictionary values and generated values (0-1):
export DICT_MIX_RATIO=0.7 # 70% dictionary values, 30% random
export DICT_MIX_RATIO=0.0 # Only random values
export DICT_MIX_RATIO=1.0 # Only dictionary values (if available)
Default: 0.5
(50/50)
Allows focusing on specific Redis commands:
# Focus on a single command (30% probability)
export REDIS_FOCUS_COMMANDS="SET"
# Focus on multiple commands (50% probability for any of them)
export REDIS_FOCUS_COMMANDS="SET,GET,HSET,SADD"
# Disable focus commands
unset REDIS_FOCUS_COMMANDS
export REDIS_HOST="127.0.0.1" # Redis/Dragonfly host
export REDIS_PORT="6379" # Redis/Dragonfly port
export OUTPUT_DIR="./output" # AFL++ output directory
export INPUT_DIR="./input" # Initial test cases directory
export MAX_COMMANDS="30" # Maximum commands per test
redis_fuzzer.py
- Main fuzzer with AFL++ supportredis_commands.py
- Redis command definitions and data generatorsredis_dict_generator.py
- Dictionary generator for AFL++run_afl_fuzzing.sh
- Test execution scriptinput/
- Initial test casesoutput/
- AFL++ results (crashes, hangs, queue)
- Random generation - Completely random commands and arguments
- Dictionary generation - Using predefined values
- Mixed strategy - Combination of both approaches
- Focus testing - Concentration on specific commands
Various data types are generated:
- Regular strings
- Special characters
- Escape sequences
- Binary data
- JSON structures
- Vector data
Edit REDIS_COMMANDS
in redis_commands.py
:
"MYCOMMAND": {
"args": ["key", "value"],
"optional_args": ["option1", "option2"]
}
Add to DATA_TYPES
:
"mytype": lambda: generate_my_custom_data()