forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
KFuzzTest: all the changes made. #9
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
Open
ethangraham2001
wants to merge
73
commits into
master
Choose a base branch
from
kfuzztest/relocations-revisited
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.
Open
Changes from all commits
Commits
Show all changes
73 commits
Select commit
Hold shift + click to select a range
1e0587e
Add simple configuration for kftf module that is built with kernel
43dc893
kftf: Add init and exit functions to module
42d6acc
kftf: simple sysfs that accepts a struct for a single function and the
4a35a64
kftf: allow tests with macro definitions in .kftf section of binary.
e8992cb
kftf: fixx sizeof check so that it checks against the provided type.
d7adb90
kftf: add metadata file per fuzzed function - this contains the name of
ca5ba48
move int_sqrt test out of kftf_tests file and into the math source
96ae8d5
kftf: address PR comments and make the FUZZ_TEST interface a lot more
ece3042
kftf: update include block so that the relative include (kftf_tests.h)
07bfafa
delete unused file kftf_simple_fuzzer
0c5cd7e
kftf: per test-case input buffer with mutex
a4bb002
kftf: update kftf_fuzzable test
0bddc3f
kftf: add some comments to module main file and kftf header file
5971467
kftf: replace static test cases buffer with kmalloc'd one.
d799f5c
kftf: replace input buffers for callback with dynamically allocated
aae72ff
kftf: replace heap allocated input buffer with function-local stack
72e3dec
kftf: fix bug in input reading logic.
6673d6f
kftf: work in progress on domain constraints. Need to see about exposing
95a0a01
kftf: allow for range constraints by expanding constraint struct.
581f240
kftf: move some stuff around and enforce 64 byte alignment of KFuzzTest
a83dee7
kftf: add annotations macros to express field types (for example
8e1f787
kfuzztest: add array annotation
c74d33a
kftf: remove int_sqrt test which is no longer really needed, added
6b03486
kftf: remove some prints from write_input_callback, update test case to
ba24eb3
kftf: introduce new buffer for payload that provides alignment
799cdcd
kftf: harden binary input parsing
51cadf2
kfuzztest: update naming from "kftf" to "kfuzztest"
e328953
kfuzztest: cleanup code and update documentation
8cb9faa
kfuzztest: remove dummy test file
aeeb29f
kfuzztest: update header comment in kfuzztest_main.c
57fddce
kfuzztest: update macros to fix naming
4ebed5f
kfuzztest: align targets to 32-byte boundary
fd61eeb
linux/kfuzztest: update serialization format for KFuzzTest inputs
c14dbe8
kfuzztest: reduce sizes of fields to 32-bit to reduce wastage
e763e70
kfuzztest: refactor code, introduce distinct and poisoned modes.
76c3b85
kfuzztest: extract relocations logic into separate .c file.
f0bd54a
kfuzztest: refactoring functions into separate .c files, modify kasan
624a566
kfuzztest: add toy example
0ccd3a3
kfuzztest: backup before only supporting poisoned mode
614ce92
kfuzztest: relocate in poison mode - the new only mode
62053d4
kfuzztest: update poisoning to use kasan_poison_last_granule
5116dcc
kfuzztest: cleanups WIP
83dfd18
kfuzztest: remove unnecessary padding from kfuzztest.h structs
60f56f6
kfuzztest: add SPDX headers to all new files
3e9815e
kfuzztest: add help section to KConfig.kfuzztest
cc985fe
kfuzztest: update comments and one code block refactored
4ad76d0
kfuzztest: move examples to .c file
14f3851
kfuzztest: wrap KFUZZTEST_TABLE def in an ifdef block
bd5d833
kfuzztest: start documentation
f39fd77
kfuzztest: add Google copyright notice, remove ifdefs in .c file
af9d76f
kfuzztest: fix parsing logic that didn't account for padding
1a286cb
kfuzztest: update examples file
b25969f
kfuzztest: update state name from st to state
3f96f02
kfuzztest: remove extraneous braces, prints, and add a check in poison
1cba6b1
kfuzztest: add a debug helper function
c85f16b
kfuzztest: poison region preceding payload to catch underflows
4820368
kfuzztest: update overflow example, add underflow example
366d8bb
kfuzztest: define macros for granule size and slab redzone
1f0ea22
kfuzztest: fix example so that it actually overflows
7b6ff73
kfuzztest: add stricter input parsing and validation, fix nits
f1cd01f
kfuzztest: more validation.
be3ba18
kfuzztest: assume at 8 bytes of padding before payload
eab275f
kfuzztest: add GE and LT domain constraints for completeness
c223a37
kfuzztest: remove __kfuzztest_write_cb_common as we no longer need it.
55f9fe6
kfuzztest: documentation updates
5ba009f
kfuzztest: updates doc comments for consistency
c22f0fc
kfuzztest: update allocation / error handling for debufs_state
1eee647
kfuzztest: file header comments
fd8b6ec
kfuzztest: update some kasan poison logic and comments
f7ee465
kfuzztest: update test case comments
5411510
kfuzztest: remove no longer needed CONFIG_KASAN check
7ed2876
kfuzztest: update KConfig dependencies and help description
496ceef
kfuzztest: move period out of a quoted region
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,181 @@ | ||
| .. SPDX-License-Identifier: GPL-2.0 | ||
| .. Copyright 2025 Google LLC | ||
|
|
||
| Kernel Fuzz Testing Framework (KFuzzTest) | ||
| ========================================= | ||
|
|
||
| Overview | ||
| -------- | ||
|
|
||
| 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. | ||
|
|
||
| The framework consists of four main components: | ||
|
|
||
| 1. An API, based on the ``FUZZ_TEST`` macro, for defining test targets | ||
| directly in the kernel tree. | ||
| 2. A binary serialization format for passing complex, pointer-rich data | ||
| structures from userspace to the kernel. | ||
| 3. A ``debugfs`` interface through which a userspace fuzzer submits | ||
| serialized test inputs. | ||
| 4. Metadata embedded in dedicated ELF sections of the ``vmlinux`` binary to | ||
| allow for the discovery of available fuzz targets by external tooling. | ||
|
|
||
| Supported Architectures | ||
| ----------------------- | ||
|
|
||
| KFuzzTest is currently only supported for x86_64. | ||
|
|
||
| Usage | ||
| ----- | ||
|
|
||
| To enable KFuzzTest, configure the kernel with:: | ||
|
|
||
| CONFIG_KFUZZTEST=y | ||
|
|
||
| which depends on ``CONFIG_DEBUGFS`` for receiving userspace inputs. | ||
|
|
||
| Declaring a KFuzzTest target | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| A fuzz target is defined directly in a .c file, typically alongside the function | ||
| being tested. This process involves three main parts: defining an input | ||
| structure, writing the test body using the ``FUZZ_TEST`` macro, and optionally | ||
| adding metadata for the fuzzer. | ||
|
|
||
| The following example illustrates how to create a fuzz target for a function | ||
| ``int process_data(const char *data, size_t len)``. | ||
|
|
||
| .. code-block:: c | ||
|
|
||
| // 1. Define a struct to model the inputs for the function under test. | ||
| // Each field corresponds to an argument needed by the function. | ||
| struct process_data_inputs { | ||
| const char *data; | ||
| size_t len; | ||
| }; | ||
|
|
||
| // 2. Define the fuzz target using the FUZZ_TEST macro. | ||
| // The first parameter is a unique name for the target. | ||
| // The second parameter is the input struct defined above. | ||
| FUZZ_TEST(test_process_data, struct process_data_inputs) | ||
| { | ||
| // Within this body, the 'arg' variable is a pointer to a | ||
| // fully initialized 'struct process_data_inputs'. | ||
|
|
||
| // 3. (Optional) Add constraints to define preconditions. | ||
| // This check ensures 'arg->data' is not NULL. If the condition | ||
| // is not met, the test exits early. This also creates metadata | ||
| // to inform the fuzzer. | ||
| KFUZZTEST_EXPECT_NOT_NULL(process_data_inputs, data); | ||
|
|
||
| // 4. (Optional) Add annotations to provide semantic hints. | ||
| // This annotation informs the fuzzer that the 'len' field | ||
| // is the length of the buffer pointed to by 'data'. | ||
| // Annotations do not add any runtime checks. | ||
| KFUZZTEST_ANNOTATE_LEN(process_data_inputs, len, data); | ||
|
|
||
| // 5. Call the kernel function with the provided inputs. | ||
| // Memory errors like out-of-bounds accesses on 'arg->data' will | ||
| // be detected by KASAN or other memory error detection tools. | ||
| process_data(arg->data, arg->len); | ||
| } | ||
|
|
||
| KFuzzTest provides two families of macros to improve the quality of fuzzing: | ||
|
|
||
| - ``KFUZZTEST_EXPECT_*``: These macros define constraints, which are | ||
| preconditions that must be true for the test to proceed. They are enforced | ||
| with a runtime check in the kernel. If a check fails, the current test run is | ||
| aborted. This metadata helps the userspace fuzzer avoid generating invalid | ||
| inputs. | ||
|
|
||
| - ``KFUZZTEST_ANNOTATE_*``: These macros define annotations, which are purely | ||
| semantic hints for the fuzzer. They do not add any runtime checks and exist | ||
| only to help the fuzzer generate more intelligent and structurally correct | ||
| inputs. For example, KFUZZTEST_ANNOTATE_LEN links a size field to a pointer | ||
| field, which is a common pattern in C APIs. | ||
|
|
||
| Input Format | ||
| ------------ | ||
|
|
||
| KFuzzTest targets receive their inputs from userspace via a write to a dedicated | ||
| debugfs ``/sys/kernel/debug/kfuzztest/<test-name>/input``. | ||
|
|
||
| The data written to this file must be a single binary blob that follows a | ||
| specific serialization format. This format is designed to allow complex, | ||
| pointer-rich C structures to be represented in a flat buffer, requiring only a | ||
| single kernel allocation and copy from userspace. | ||
|
|
||
| The format consists of three main parts laid out sequentially: a region array, | ||
| a relocation table, and the payload.:: | ||
|
|
||
| +----------------+---------------------+-----------+----------------+ | ||
| | region array | relocation table | padding | payload | | ||
| +----------------+---------------------+-----------+----------------+ | ||
|
|
||
| Region Array | ||
| ~~~~~~~~~~~~ | ||
|
|
||
| This component is a header that describes how the raw data in the Payload is | ||
| partitioned into logical memory regions. It consists of a count of regions | ||
| followed by an array of ``struct reloc_region``, where each entry defines a | ||
| single region with its size and offset from the start of the payload. | ||
|
|
||
| .. code-block:: c | ||
|
|
||
| struct reloc_region { | ||
| uint32_t offset; | ||
| uint32_t size; | ||
| }; | ||
|
|
||
| struct reloc_region_array { | ||
| uint32_t num_regions; | ||
| struct reloc_region regions[]; | ||
| }; | ||
|
|
||
| By convention, region 0 represents the top-level input struct that is passed | ||
| as the arg variable to the FUZZ_TEST body. Subsequent regions typically | ||
| represent data buffers pointed to by fields within that struct. Region array | ||
| entries must be ordered by offset ascending, and must not overlap with one | ||
| another. | ||
|
|
||
| Relocation Table | ||
| ~~~~~~~~~~~~~~~~ | ||
|
|
||
| The relocation table provides the instructions for the kernel to "hydrate" the | ||
| payload by patching pointer fields. It contains an array of | ||
| ``struct reloc_entry`` items. Each entry acts as a linking instruction, | ||
| specifying: | ||
|
|
||
| - The location of a pointer that needs to be patched (identified by a region | ||
| ID and an offset within that region). | ||
|
|
||
| - The target region that the pointer should point to (identified by the | ||
| target's region ID) or ``KFUZZTEST_REGIONID_NULL`` if the pointer is ``NULL``. | ||
|
|
||
| This table also specifies the amount of padding between its end and the start | ||
| of the payload, which should be at least 8 bytes. | ||
|
|
||
| Payload | ||
| ~~~~~~~ | ||
|
|
||
| The payload contains the raw binary data for all regions, concatenated together | ||
| according to their specified offsets. | ||
|
|
||
| - Alignment: The start of the payload must be aligned to the most restrictive | ||
| alignment requirement of all its constituent regions. The framework ensures | ||
| that each region within the payload is then placed at an offset that respects | ||
| its own type's alignment. | ||
|
|
||
| - Padding and Poisoning: The space between the end of one region's data and the | ||
| beginning of the next must be sufficient for padding. In KASAN builds, | ||
| KFuzzTest poisons this unused padding, allowing for precise detection of | ||
| out-of-bounds memory accesses between adjacent buffers. This padding should | ||
| be at least ``KFUZZTEST_POISON_SIZE`` bytes as defined in | ||
| `include/linux/kfuzztest.h``. |
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.