-
Notifications
You must be signed in to change notification settings - Fork 1.3k
KFuzzTest: proof of concept #6280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
ethangraham2001
wants to merge
59
commits into
google:master
Choose a base branch
from
ethangraham2001:kfuzztest/proof-of-concept
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
59 commits
Select commit
Hold shift + click to select a range
885914b
pkg/kcov: add pkg/kcov
2fe3264
kfuzztest: add pseudo syscall, attribute, and serialization
83dccf3
prog: add Extend method
95170f3
pkg/kfuzztest: add pkg/kfuzztest
b3c287d
syz-kfuzztest: add syz-kfuzztest tool
a1ae170
kfuzztest: add special dedicated and update manager config
d832b41
tools: add kfuzztest-gen tool
e5eea1c
docs: add kfuzztest and syz-kfuzztest documentation
ce0452b
sys/linux: add no_generate attribute to syz_kfuzztest_run
92a6ff7
prog/encodingexec: fix KFuzzTest ID updates
0bfd1a1
syz-manager: update enabledCalls earlier
e231400
prog: add ignoreLengths parameter to getMutationPrio interface
369c83e
pkg/mgrconfig: extract KFuzzTest targets in during Load
9635501
prog/target: cache syz_kfuzztest_run ID
438b969
pkg/kfuzztest: return astError
7bbf416
prog: forcibly null-terminate strings for KFuzzTest calls
fa70baa
prog: only generate one call per KFuzzTest program
55f0813
syz-kfuzztest: small changes, use fuzzer stats instead of custom
065ad6f
syz-kfuzztest: remove references to callhistogram, no context as field
44d57b9
pkg/mgrconfig: remove logFunc from parameters
264ea65
pkg/kfuzztest,pkg/kfuzztest-manager: move manager to new separate pkg
ad12623
pkg,prog: add standard headers to new files
a9f198a
pkg/kfuzztest: merge helpers.go into kfuzztest.go
d8a201c
prog: update null-termination for KFuzzTest targets
eb252e9
pkg/kfuzztest: propagate errors when reading elf strings
33d7314
executor: return negative error code in syz_kfuzztest_run failure paths
90cc9b1
executor: check for bytes_written != input_data_size in kfuzztest call
5e3621a
pkg/kfuzztest: remove unused log import
ec83a81
sys/linux: add meta arches for syz-kfuzztest-run, and license header
002f494
prog: ignore return value when caching syz_kfuzztest_run ID in lazyInit
1637b32
pkg/kfuzztest: validate length of data in fromBytes
316e5c5
tools/kfuzztest-gen: add license header
14a3ec7
pkg/kfuzztest: implement String() method for ExtractAllResult
dd8b054
tools: handle error returned by ActivateKFuzzTestTargets
e7226c8
kfuzztest: move target extraction back into manager, add caching
85f1512
pkg/kfuzztest-manager: fix coverage collection + small changes
9b48b81
pkg/kfuzztest: remove unused SupportsKFuzzTest()
b5372eb
pkg/fuzzer: implement RecommendedCalls() method for fuzzer
89c3400
pkg/kfuzztest: fix coverage collection and output
ad13bd5
tools/syz-prog2c: remove a log statement
2850032
tools/kfuzztest-gen: update logging / exiting situation
5f1ea62
tools/kfuzztest-gen: add usage, simplify args parsing
fb0c571
pkg/vminfo: add checker function for syz_kfuzztest_run
b40d484
docs: update usage in readme for syz-kfuzztest
ea1d0b7
pkg/kfuzztest: add a golden tests for description generation
f0707eb
pkg/kfuzztest: small fixes that came to light during testing
ae805f2
prog: move KFuzzTest null termination to encoding logic
e5b9888
prog/mutation: disable special pointers for KFuzzTest calls
7904f92
pkg/kfuzztest: add more types to builder
dadb4de
pkg/kfuzztest: use dwarf type in syscall description generation
68853b8
pkg/kfuzztest: remove unused log import
c9bf9cf
various: Fix lint errors on CI
2c2a6ad
docs/kfuzztest: remove trailing whitespace
d0a7a4e
prog/kfuzztest: use minalignment property introduced into KFuzzTest
ee5cc32
pkg/kfuzztest: fix nil pointer deref and annotations processing
fe3ca97
prog/kfuzztest: align payload to kFuzzTestPoisonSize
0e8eba3
pkg/kfuzztest: fix lint
250e138
pkg/kfuzztest: remove C++ syntax from common.h
d6cdb29
pkg/vminfo: make kfuzztest_run always supported
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
# KFuzzTest Integration With syzkaller | ||
|
||
KFuzzTest, introduced initially in [this RFC](https://lore.kernel.org/all/[email protected]/) | ||
is a framework for exposing internal kernel functions to a userspace fuzzing | ||
engine like syzkaller. As the kernel docs put it: | ||
|
||
> The Kernel Fuzz Testing Framework (KFuzzTest) is a framework designed to | ||
> expose internal kernel functions to a userspace fuzzing engine. | ||
> | ||
> It is intended for testing stateless or low-state functions that are difficult | ||
> to reach from the system call interface, such as routines involved in file | ||
> format parsing or complex data transformations. This provides a method for | ||
> in-situ fuzzing of kernel code without requiring that it be built as a | ||
> separate userspace library or that its dependencies be stubbed out. | ||
|
||
This document introduces how syzkaller integrates with KFuzzTest. | ||
|
||
## Getting Started | ||
|
||
Firstly, ensure that the KFuzzTest patch series has been applied to your Linux | ||
tree. | ||
|
||
As of the 22nd of August 2025, the most up-to-date version can be found in | ||
[this Linux Kernel RFC](https://lore.kernel.org/all/[email protected]/). | ||
|
||
Once this is done, KFuzzTest targets can be defined on arbitrary kernel | ||
functions using the `FUZZ_TEST` macro as described in the kernel docs in | ||
`Documentation/dev-tools/kfuzztest.rst`. | ||
|
||
### Configuration Options | ||
|
||
Ensure that the following KConfig options are enabled for your kernel image: | ||
|
||
- `CONFIG_DEBUG_FS` (used as a communication interface by KFuzzTest). | ||
- `CONFIG_DEBUG_KERNEL`. | ||
- `CONFIG_KFUZZTEST`. | ||
|
||
It is also **highly** recommended to enable the following KConfig options for | ||
more effective fuzzing. | ||
|
||
- `CONFIG_KASAN` (catch memory bugs such as out-of-bounds-accesses). | ||
- `CONFIG_KCOV` (to enable coverage guided fuzzing). | ||
|
||
## Fuzzing KFuzzTest Targets | ||
|
||
Syzkaller implements three ways to fuzz KFuzzTest targets: | ||
|
||
1. `syz-manager` integration with static targets | ||
2. `syz-manager` with dynamic targets | ||
3. `syz-kfuzztest`: a standalone tool that runs inside a VM, discovers KFuzzTest | ||
targets dynamically, and fuzzes them. | ||
|
||
### 1. `syz-manager` with static targets | ||
|
||
Configuration for this method is identical to `syz-manager`, and is designed to | ||
make it easy to integrate KFuzzTest fuzzing into existing continuous fuzzing | ||
deployments. | ||
|
||
One must first write a syzlang description for the KFuzzTest target(s) of | ||
interest, for example in `/sys/linux/my_kfuzztest_target.txt`. Each target | ||
should have the following format: | ||
|
||
``` | ||
some_buffer { | ||
buf ptr[inout, array[int8]] | ||
buflen len[buf, int64] | ||
} | ||
|
||
kfuzztest_underflow_on_buffer(name ptr[in, string["test_underflow_on_buffer"]], data ptr[in, some_buffer], len bytesize[data]) (kfuzz_test) | ||
``` | ||
|
||
Where: | ||
|
||
- The first argument should be a string pointer to the name of the fuzz target, | ||
i.e,. the name of its `debugfs` input directory in the kernel. | ||
- The second should be a pointer to a struct of the type that the fuzz | ||
target accepts as input. | ||
- The third should be the size in bytes of the input argument. | ||
- The call is annotated with attribute `kfuzz_test`. | ||
|
||
For more information on writing syzkaller descriptions attributes, consult the | ||
[syscall description](syscall_descriptions.md) and [syscall description syntax](syscall_descriptions_syntax.md) | ||
documentation files. | ||
|
||
To facilitate the tedious task of writing `syz_kfuzztest_run` descriptions, a | ||
tool (`tools/kfuzztest-gen`) is provided to automatically generate these from a | ||
`vmlinux` binary. One can run the tool and paste the output into a syzlang file. | ||
|
||
```sh | ||
go run ./tools/kfuzztest-gen --vmlinux=path/to/vmlinux | ||
``` | ||
|
||
After writing these descriptions to a file under the `/sys/linux/` directory | ||
(for example, `/sys/linux/my_fuzz_targets.txt`), they need to be compiled with | ||
`make descriptions`. | ||
|
||
Finally, the targets can be enabled in `syz-manager` config file in the | ||
`enable_syscalls` field, e.g. | ||
|
||
```json | ||
{ | ||
"enable_syscalls": [ "syz_kfuzztest_run$test_underflow_on_buffer" ] | ||
} | ||
``` | ||
|
||
### 2. `syz-manager` with dynamic discovery | ||
|
||
This feature greatly reduces the amount of setup needed for fuzzing KFuzzTest | ||
targets, by discovering them all dynamically at launch. | ||
|
||
This approach is considered less stable than the previous as it involves | ||
generating descriptions for KFuzzTest targets without human input and then | ||
immediately fuzzing them. It does, however, better reflect our intentions for | ||
KFuzzTest: continuously fuzzing the kernel with a dynamically changing set of | ||
targets with little intervention from syzkaller maintainers. | ||
|
||
To enable this feature, configure the experimental `enable_kfuzztest` option in | ||
the manager configuration, which enables all discovered KFuzzTest targets by | ||
default. | ||
|
||
```json | ||
{ | ||
"enable_kfuzztest": true | ||
} | ||
``` | ||
|
||
**IMPORTANT:** for this to work, it is essential for the kernel image pointed to | ||
by the manager configuration is built with `CONFIG_DWARF4` or `CONFIG_DWARF5` | ||
enabled, as dynamic target discovery depends on these symbols being emitted. | ||
|
||
### 3. `syz-kfuzztest`, an in-VM standalone tool | ||
|
||
In contrast with `syz-manager`, `syz-kfuzztest` is designed to perform coverage | ||
guided fuzzing from within a VM directly rather than orchestrating a fleet of | ||
VMs. It is primarily targetted at development-time fuzzing, rather than longterm | ||
continuous fuzzing. | ||
|
||
For more information, consult [the `syz-kfuzztest` documentation](syz-kfuzztest.md). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
# `syz-kfuzztest` | ||
|
||
`syz-kfuzztest` is a standalone tool for fuzzing KFuzzTest targets from within | ||
the kernel being fuzzed (e.g., a VM). | ||
|
||
It is intended to be used for development-time fuzzing rather than continuous | ||
fuzzing like `syz-manager`. | ||
|
||
For more information on KFuzzTest, consult the [dedicated readme](kfuzztest.md) | ||
or the Kernel documentation. | ||
|
||
## Usage (in-VM fuzzing) | ||
|
||
### Getting the Kernel Ready | ||
|
||
It is important that the target Kernel image has the correct KConfig options | ||
enabled. Namely | ||
|
||
- `CONFIG_KFUZZTEST` | ||
- `CONFIG_DEBUG_FS` | ||
- `CONFIG_DEBUG_KERNEL` | ||
- `CONFIG_KCOV` | ||
- `CONFIG_DWARF4` or `CONFIG_DWARF5` | ||
- `CONFIG_KASAN` _(optional, choose your favorite sanitizers for a better shot | ||
at finding bugs!)_ | ||
|
||
Furthermore, as you will need to connect to the VM being tested through SSH and | ||
launch `syz-kfuzztest` _(a Go binary with LIBC dependencies)_, it is recommended | ||
to create an image for the kernel being fuzzed (e.g., a Debian Bullseye image). | ||
Detailed instructions on how to do this can be found in | ||
[this setup guide](linux/setup_ubuntu-host_qemu-vm_x86-64-kernel.md). | ||
|
||
### Building and Launching the Binary | ||
|
||
The `syz-kfuzztest` binary is built with `make syz-kfuzztest`, and is intended | ||
to run on the Kernel fuzzed. The common case for this is within a VM _(after | ||
all, the tool is trying to make the Kernel crash)_. | ||
|
||
Then, ensure that the `syz-kfuzztest` binary and `vmlinux` image are copied | ||
over into the VM. E.g., | ||
|
||
```sh | ||
scp $KERNEL/vmlinux root@my-vm:~/syz-kfuzztest/vmlinux | ||
scp $SYZKALLER/bin/syz-kfuzztest root@lmy-vm:~/syz-kfuzztest/syz-kfuzztest | ||
``` | ||
|
||
Then launched like this: | ||
|
||
``` | ||
usage: ./bin/syz-kfuzztest [flags] [enabled targets] | ||
|
||
Args: | ||
One fuzz test name per enabled fuzz test arg. If empty, defaults to | ||
all discovered targets. | ||
Example: | ||
./syz-kfuzztest -vmlinux ~/kernel/vmlinux fuzz_target_0 fuzz_target_1 | ||
Flags: | ||
-display int | ||
Number of seconds between console outputs (default 5) | ||
-threads int | ||
Number of threads (default 2) | ||
-timeout int | ||
Timeout between program executions in seconds (default 0) | ||
-vmlinux string | ||
Path to vmlinux binary (default "vmlinux") | ||
-vv int | ||
verbosity | ||
``` | ||
|
||
The enabled targets, which are listed after the flag arguments, are the names of | ||
the enabled fuzz targets. For example given some KFuzzTest targets: | ||
|
||
```c | ||
FUZZ_TEST(kfuzztest_target_1, struct input_arg_type) | ||
{ | ||
/* ... */ | ||
} | ||
|
||
FUZZ_TEST(kfuzztest_target_2, struct input_arg_type) | ||
{ | ||
/* ... */ | ||
} | ||
|
||
``` | ||
|
||
Can be fuzzed with: | ||
|
||
```bash | ||
./syz-kfuzztest -vmlinux path/to/vmlinux -threads 4 kfuzztest_target_1 kfuzztest_target_2 | ||
``` | ||
|
||
If the enabled targets list is left empty, `syz-kfuzztest` will fuzz all | ||
discovered targets in the kernel. | ||
|
||
On exit, `syz-kfuzztest` will write the collected program counters (which are | ||
collected with KCOV) into a file called `pcs.out`. These program counters can | ||
be fed into [`syz-cover`](../tools/syz-cover/syz-cover.go) to generate an HTML | ||
visualization of the lines that were covered during fuzzing. It is recommended | ||
to do this on the host machine rather than the VM. | ||
|
||
For example: | ||
|
||
```sh | ||
scp root@my-vm:~/syz-kfuzztest/pcs.out . | ||
go run tools/syz-cover -config my.cfg pcs.out # May require the -force flag. | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.