File: fuzzing.md

package info (click to toggle)
bpftrace 0.24.1-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,496 kB
  • sloc: cpp: 60,982; ansic: 10,952; python: 953; yacc: 665; sh: 536; lex: 295; makefile: 22
file content (120 lines) | stat: -rw-r--r-- 4,621 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# 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

### `BPFTRACE_MAX_AST_NODES` environment variable

When doing fuzzing, it is important to limit the number of AST nodes because
otherwise, a fuzzer might keep generating a very long program that causes a
stack overflow.  `BPFTRACE_MAX_AST_NODES` environment variable controls the
maximum number of AST nodes.

## Fuzzing with AFL

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

### Setup

The fuzzing setup relies on `nix`. See the [nix instructions](./nix.md).

### 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= \
BPFTRACE_MAX_AST_NODES=200 \
BPFTRACE_AVAILABLE_FUNCTIONS_TEST= \
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
- [#1623](https://github.com/bpftrace/bpftrace/pull/1623)
- [#1619](https://github.com/bpftrace/bpftrace/pull/1619)
- [#1580](https://github.com/bpftrace/bpftrace/pull/1580)
- [#1573](https://github.com/bpftrace/bpftrace/pull/1573)
- [#1572](https://github.com/bpftrace/bpftrace/pull/1572)
- [#1570](https://github.com/bpftrace/bpftrace/pull/1570)
- [#1568](https://github.com/bpftrace/bpftrace/pull/1568)
- [#1286](https://github.com/bpftrace/bpftrace/pull/1286)
- [#1245](https://github.com/bpftrace/bpftrace/pull/1245)
- [#1234](https://github.com/bpftrace/bpftrace/pull/1234)
- [#1229](https://github.com/bpftrace/bpftrace/pull/1229)
- [#1224](https://github.com/bpftrace/bpftrace/pull/1224)
- [#1222](https://github.com/bpftrace/bpftrace/pull/1222)
- [#1221](https://github.com/bpftrace/bpftrace/pull/1221)
- [#1210](https://github.com/bpftrace/bpftrace/pull/1210)
- [#1205](https://github.com/bpftrace/bpftrace/pull/1205)

### libFuzzer
- [#1653](https://github.com/bpftrace/bpftrace/pull/1653)
- [#1650](https://github.com/bpftrace/bpftrace/pull/1650)
- [#1622](https://github.com/bpftrace/bpftrace/pull/1622)
- [#1621](https://github.com/bpftrace/bpftrace/pull/1621)

[AFL]: https://github.com/google/AFL
[AFL++]: https://github.com/AFLplusplus/AFLplusplus