-
Notifications
You must be signed in to change notification settings - Fork 1.4k
KFuzzTest integration #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
Merged
a-nogikh
merged 15 commits into
google:master
from
ethangraham2001:kfuzztest/proof-of-concept
Sep 22, 2025
Merged
KFuzzTest integration #6280
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
da759da
pkg/kcov: add pkg/kcov
1f121a2
kfuzztest: introduce syz_kfuzztest_run pseudo-syscall
514f9db
prog/target: add Extend method
a57a728
prog/target: add fetching function for syz_kfuzztest_run ID
e265a66
pkg/kfuzztest: add pkg/kfuzztest
c53c0dd
pkg/mgrconfig: add experimental enable_kfuzztest boolean flag
c87dca0
prog: add specialized mutation for KFuzzTest calls
70db087
syz-manager: enable KFuzzTest target discovery
d35864c
pkg/corpus: add Cover() method for returning the corpus' coverage
6c56071
syz-kfuzztest: add syz-kfuzztest executable
ccb36e3
tools/kfuzztest-gen: add kfuzztest-gen tool
ff238bb
docs: add KFuzzTest documentation
aa5ee99
pkg/fuzzer: use a smaller number of recommended calls for KFuzzTest
588f504
tools/syz-prog2c: add vmlinux parsing stage for KFuzzTest
849f9ff
prog: fix syz_kfuzztest_run allocation strategy
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
Some comments aren't visible on the classic Files Changed page.
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,149 @@ | ||
| # KFuzzTest Integration With syzkaller | ||
|
|
||
| KFuzzTest, introduced initially in [this RFC](https://lore.kernel.org/all/20250813133812.926145-1-ethan.w.s.graham@gmail.com/) | ||
| 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/20250813133812.926145-1-ethan.w.s.graham@gmail.com/). | ||
|
|
||
| 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 | ||
| } | ||
| ``` | ||
|
|
||
| You must also enable pseudo-syscall `syz_kfuzztest_run`, like so: | ||
|
|
||
| ```json | ||
| { | ||
| "enable_syscalls": [ | ||
| "syz_kfuzztest_run" | ||
| ], | ||
| } | ||
| ``` | ||
|
|
||
| **IMPORTANT:** for dynamic discovery 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.
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.