Skip to content

Commit 89b70a6

Browse files
author
Ethan Graham
committed
docs: add kfuzztest and syz-kfuzztest documentation
1 parent 95fb4f7 commit 89b70a6

File tree

2 files changed

+246
-0
lines changed

2 files changed

+246
-0
lines changed

docs/kfuzztest.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# KFuzzTest Integration With syzkaller
2+
3+
KFuzzTest, introduced initially in [this RFC](https://lore.kernel.org/all/[email protected]/)
4+
is a framework for exposing internal kernel functions to a userspace fuzzing
5+
engine like syzkaller. As the kernel docs put it:
6+
7+
> The Kernel Fuzz Testing Framework (KFuzzTest) is a framework designed to
8+
> expose internal kernel functions to a userspace fuzzing engine.
9+
>
10+
> It is intended for testing stateless or low-state functions that are difficult
11+
> to reach from the system call interface, such as routines involved in file
12+
> format parsing or complex data transformations. This provides a method for
13+
> in-situ fuzzing of kernel code without requiring that it be built as a
14+
> separate userspace library or that its dependencies be stubbed out.
15+
16+
This document introduces how syzkaller integrates with KFuzzTest.
17+
18+
## Getting Started
19+
20+
Firstly, ensure that the KFuzzTest patch series has been applied to your Linux
21+
tree.
22+
23+
As of the 22nd of August 2025, the most up-to-date version can be found in
24+
[this Linux Kernel RFC](https://lore.kernel.org/all/[email protected]/).
25+
26+
Once this is done, KFuzzTest targets can be defined on arbitrary kernel
27+
functions using the `FUZZ_TEST` macro as described in the kernel docs in
28+
`Documentation/dev-tools/kfuzztest.rst`.
29+
30+
### Configuration Options
31+
32+
Ensure that the following KConfig options are enabled for your kernel image:
33+
34+
- `CONFIG_DEBUG_FS` (used as a communication interface by KFuzzTest).
35+
- `CONFIG_DEBUG_KERNEL`.
36+
- `CONFIG_KFUZZTEST`.
37+
38+
It is also **highly** recommended to enable the following KConfig options for
39+
more effective fuzzing.
40+
41+
- `CONFIG_KASAN` (catch memory bugs such as out-of-bounds-accesses).
42+
- `CONFIG_KCOV` (to enable coverage guided fuzzing).
43+
44+
## Fuzzing KFuzzTest Targets
45+
46+
Syzkaller implements three ways to fuzz KFuzzTest targets:
47+
48+
1. `syz-manager` integration with static targets
49+
2. `syz-manager` with dynamic targets
50+
3. `syz-kfuzztest`: a standalone tool that runs inside a VM, discovers KFuzzTest
51+
targets dynamically, and fuzzes them.
52+
53+
### 1. `syz-manager` with static targets
54+
55+
Configuration for this method is identical to `syz-manager`, and is designed to
56+
make it easy to integrate KFuzzTest fuzzing into existing continuous fuzzing
57+
deployments.
58+
59+
One must first write a syzlang description for the KFuzzTest target(s) of
60+
interest, for example in `/sys/linux/my_kfuzztest_target.txt`. Each target
61+
should have the following format:
62+
63+
```
64+
some_buffer {
65+
buf ptr[inout, array[int8]]
66+
buflen len[buf, int64]
67+
}
68+
69+
kfuzztest_underflow_on_buffer(name ptr[in, string["test_underflow_on_buffer"]], data ptr[in, some_buffer], len bytesize[data]) (kfuzz_test)
70+
```
71+
72+
Where:
73+
74+
- The first argument should be a string pointer to the name of the fuzz target,
75+
i.e,. the name of its `debugfs` input directory in the kernel.
76+
- The second should be a pointer to a struct of the type that the fuzz
77+
target accepts as input.
78+
- The third should be the size in bytes of the input argument.
79+
- The call is annotated with attribute `kfuzz_test`.
80+
81+
For more information on writing syzkaller descriptions attributes, consult the
82+
[syscall description](syscall_descriptions.md) and [syscall description syntax](syscall_descriptions_syntax.md)
83+
documentation files.
84+
85+
To facilitate the tedious task of writing `syz_kfuzztest_run` descriptions, a
86+
tool (`tools/kfuzztest-gen`) is provided to automatically generate these from a
87+
`vmlinux` binary. One can run the tool and paste the output into a syzlang file.
88+
89+
```sh
90+
go run ./tools/kfuzztest-gen --vmlinux=path/to/vmlinux
91+
```
92+
93+
After writing these descriptions to a file under the `/sys/linux/` directory
94+
(for example, `/sys/linux/my_fuzz_targets.txt`), they need to be compiled with
95+
`make descriptions`.
96+
97+
Finally, the targets can be enabled in `syz-manager` config file in the
98+
`enable_syscalls` field, e.g.
99+
100+
```json
101+
{
102+
"enable_syscalls": [ "syz_kfuzztest_run$test_underflow_on_buffer" ]
103+
}
104+
```
105+
106+
### 2. `syz-manager` with dynamic discovery
107+
108+
This feature greatly reduces the amount of setup needed for fuzzing KFuzzTest
109+
targets, by discovering them all dynamically at launch.
110+
111+
This approach is considered less stable than the previous as it involves
112+
generating descriptions for KFuzzTest targets without human input and then
113+
immediately fuzzing them. It does, however, better reflect our intentions for
114+
KFuzzTest: continuously fuzzing the kernel with a dynamically changing set of
115+
targets with little intervention from syzkaller maintainers.
116+
117+
To enable this feature, configure the experimental `enable_kfuzztest` option in
118+
the manager configuration, which enables all discovered KFuzzTest targets by
119+
default.
120+
121+
```json
122+
{
123+
"enable_kfuzztest": true
124+
}
125+
```
126+
127+
**IMPORTANT:** for this to work, it is essential for the kernel image pointed to
128+
by the manager configuration is built with `CONFIG_DWARF4` or `CONFIG_DWARF5`
129+
enabled, as dynamic target discovery depends on these symbols being emitted.
130+
131+
### 3. `syz-kfuzztest`, an in-VM standalone tool
132+
133+
In contrast with `syz-manager`, `syz-kfuzztest` is designed to perform coverage
134+
guided fuzzing from within a VM directly rather than orchestrating a fleet of
135+
VMs. It is primarily targetted at development-time fuzzing, rather than longterm
136+
continuous fuzzing.
137+
138+
For more information, consult [the `syz-kfuzztest` documentation](syz-kfuzztest.md).

docs/syz-kfuzztest.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# `syz-kfuzztest`
2+
3+
`syz-kfuzztest` is a standalone tool for fuzzing KFuzzTest targets from within
4+
the kernel being fuzzed (e.g., a VM).
5+
6+
It is intended to be used for development-time fuzzing rather than continuous
7+
fuzzing like `syz-manager`.
8+
9+
For more information on KFuzzTest, consult the [dedicated readme](kfuzztest.md)
10+
or the Kernel documentation.
11+
12+
## Usage (in-VM fuzzing)
13+
14+
### Getting the Kernel Ready
15+
16+
It is important that the target Kernel image has the correct KConfig options
17+
enabled. Namely
18+
19+
- `CONFIG_KFUZZTEST`
20+
- `CONFIG_DEBUG_FS`
21+
- `CONFIG_DEBUG_KERNEL`
22+
- `CONFIG_KCOV`
23+
- `CONFIG_DWARF4` or `CONFIG_DWARF5`
24+
- `CONFIG_KASAN` _(optional, choose your favorite sanitizers for a better shot
25+
at finding bugs!)_
26+
27+
Furthermore, as you will need to connect to the VM being tested through SSH and
28+
launch `syz-kfuzztest` _(a Go binary with LIBC dependencies)_, it is recommended
29+
to create an image for the kernel being fuzzed (e.g., a Debian Bullseye image).
30+
Detailed instructions on how to do this can be found in
31+
[this setup guide](linux/setup_ubuntu-host_qemu-vm_x86-64-kernel.md).
32+
33+
### Building and Launching the Binary
34+
35+
The `syz-kfuzztest` binary is built with `make syz-kfuzztest`, and is intended
36+
to run on the Kernel fuzzed. The common case for this is within a VM _(after
37+
all, the tool is trying to make the Kernel crash)_.
38+
39+
Then, ensure that the `syz-kfuzztest` binary and `vmlinux` image are copied
40+
over into the VM. E.g.,
41+
42+
```sh
43+
scp $KERNEL/vmlinux root@my-vm:~/syz-kfuzztest/vmlinux
44+
scp $SYZKALLER/bin/syz-kfuzztest root@lmy-vm:~/syz-kfuzztest/syz-kfuzztest
45+
```
46+
47+
Then launched like this:
48+
49+
```
50+
usage: ./bin/syz-kfuzztest [flags] [enabled targets]
51+
52+
Args:
53+
One fuzz test name per enabled fuzz test arg. If empty, defaults to
54+
all discovered targets.
55+
Example:
56+
./syz-kfuzztest -vmlinux ~/kernel/vmlinux fuzz_target_0 fuzz_target_1
57+
Flags:
58+
-display int
59+
Display interval (default 5)
60+
-display-progs
61+
If enabled, display the last executed prog for each target
62+
-threads int
63+
Number of threads (default 2)
64+
-timeout int
65+
Timeout in milliseconds
66+
-vmlinux string
67+
Path to vmlinux binary (default "vmlinux")
68+
-vv int
69+
verbosity
70+
```
71+
72+
The enabled targets, which are listed after the flag arguments, are the names of
73+
the enabled fuzz targets. For example given some KFuzzTest targets:
74+
75+
```c
76+
FUZZ_TEST(kfuzztest_target_1, struct input_arg_type)
77+
{
78+
/* ... */
79+
}
80+
81+
FUZZ_TEST(kfuzztest_target_2, struct input_arg_type)
82+
{
83+
/* ... */
84+
}
85+
86+
```
87+
88+
Can be fuzzed with:
89+
90+
```bash
91+
./syz-kfuzztest -vmlinux path/to/vmlinux -threads 4 kfuzztest_target_1 kfuzztest_target_2
92+
```
93+
94+
If the enabled targets list is left empty, `syz-kfuzztest` will fuzz all
95+
discovered targets in the kernel.
96+
97+
On exit, `syz-kfuzztest` will write the collected program counters (which are
98+
collected with KCOV) into a file called `pcs.out`. These program counters can
99+
be fed into [`syz-cover`](../tools/syz-cover/syz-cover.go) to generate an HTML
100+
visualization of the lines that were covered during fuzzing. It is recommended
101+
to do this on the host machine rather than the VM.
102+
103+
For example:
104+
105+
```sh
106+
scp root@my-vm:~/syz-kfuzztest/pcs.out .
107+
go run tools/syz-cover -config my.cfg pcs.out # May require the -force flag.
108+
```

0 commit comments

Comments
 (0)