Back to Bpftrace

Fuzzing bpftrace

docs/fuzzing.md

0.25.14.1 KB
Original Source

Fuzzing bpftrace

This document is for bpftrace developers.

Introduction

Fuzzing is a method to find bugs in a program automatically. In fuzzing, a fuzzer generates the program input and give it and observes whether the program crashes or not. The most commonly used fuzzing method is called gray box fuzzing, which uses coverage (which parts the program executes) information to generate input efficiently.

Fuzzing can be divided into two types according to the target of fuzzing: one that targets the entire program for fuzzing, such as AFL, and the other that targets a specific function, such as libFuzzer. In the former case, a fuzzer generates and supplies the program's input, so you don't need to modify the program. This is not always efficient for large programs, but still can find many bugs. The latter is efficient for a function to be fuzzed because a fuzzer directly targets the function, but we need to write some glue code to connect a fuzzer and the function.

Options

Fuzzing with AFL

Before starting, it is highly recommended to read the AFL or AFLPlusPlus documentation.

Setup

The fuzzing setup relies on nix. See the nix instructions.

Compile

To use AFL, we need to compile the program with the AFL compiler. If you are using nix, you would enter a development shell and build as follows:

nix develop #.bpftrace-fuzz
CC=afl-clang-fast CXX=afl-clang-fast++ cmake -B build-fuzz -DCMAKE_BUILD_TYPE=Debug -DBUILD_ASAN=1

then, in order to build the tree:

cd build-fuzz && AFL_USE_ASAN=1 make -j$(nproc)

Note that the address sanitizer might take a lot of memory. If you want to fuzz without it, please remove AFL_USE_ASAN and -DBUILD_ASAN.

Running

AFL recommends some settings for efficient fuzzing:

echo core | sudo tee -a /proc/sys/kernel/core_pattern
cd /sys/devices/system/cpu
echo performance | sudo tee cpu*/cpufreq/scaling_governor

Then, fuzz away! AFL and the address sanitizer have a lot of settings, so please read documentation for the details. The currently recommended way to run the fuzzer is by using the --test=codegen mode and providing overrides:

AFL_NO_AFFINITY=1 \
ASAN_OPTIONS=abort_on_error=1,symbolize=0 \
BPFTRACE_BTF= \
afl-fuzz -a text -M 0 -m none -i ./input -o ./output -t 3000 -- \
     src/bpftrace --test=codegen @@ 2>/dev/null

In the above, -i specifics the input directory, and -o specifies the output directory. In the input directory, you need to put something to start fuzzing. The most simple example is echo a > input/a. More sophisticated inputs can be created by using sample bpftrace programs from the source directory, tests or other locations. If some inputs that cause a program crash is found, output/crashes contains them.

The timeout for each execution (in milliseconds) is provided by -t.

Finally, '@@' will be replaced by the input file generated by the fuzzer.

Found bugs

AFL

libFuzzer