On Tue, 2 Sept 2025 at 00:43, Ethan Graham <ethan.w.s.graham@xxxxxxxxx> wrote: > > From: Ethan Graham <ethangraham@xxxxxxxxxx> > > This patch series introduces KFuzzTest, a lightweight framework for > creating in-kernel fuzz targets for internal kernel functions. > > The primary motivation for KFuzzTest is to simplify the fuzzing of > low-level, relatively stateless functions (e.g., data parsers, format > converters) that are difficult to exercise effectively from the syscall > boundary. It is intended 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. Using a simple macro-based API, developers > can add a new fuzz target with minimal boilerplate code. > > The core design consists of three main parts: > 1. A `FUZZ_TEST(name, struct_type)` macro that allows developers to > easily define a fuzz test. > 2. A binary input format that allows a userspace fuzzer to serialize > complex, pointer-rich C structures into a single buffer. > 3. Metadata for test targets, constraints, and annotations, which is > emitted into dedicated ELF sections to allow for discovery and > inspection by userspace tools. These are found in > ".kfuzztest_{targets, constraints, annotations}". > > To demonstrate this framework's viability, support for KFuzzTest has been > prototyped in a development fork of syzkaller, enabling coverage-guided > fuzzing. To validate its end-to-end effectiveness, we performed an > experiment by manually introducing an off-by-one buffer over-read into > pkcs7_parse_message, like so: > > -ret = asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen); > +ret = asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen + 1); > > A syzkaller instance fuzzing the new test_pkcs7_parse_message target > introduced in patch 7 successfully triggered the bug inside of > asn1_ber_decoder in under a 30 seconds from a cold start. > > This RFC continues to seek feedback on the overall design of KFuzzTest > and the minor changes made in V2. We are particularly interested in > comments on: > - The ergonomics of the API for defining fuzz targets. > - The overall workflow and usability for a developer adding and running > a new in-kernel fuzz target. > - The high-level architecture. > > The patch series is structured as follows: > - Patch 1 adds and exposes a new KASAN function needed by KFuzzTest. > - Patch 2 introduces the core KFuzzTest API and data structures. > - Patch 3 adds the runtime implementation for the framework. > - Patch 4 adds a tool for sending structured inputs into a fuzz target. > - Patch 5 adds documentation. > - Patch 6 provides example fuzz targets. > - Patch 7 defines fuzz targets for real kernel functions. > > Changes in v2: > - Per feedback from Eric Biggers and Ignat Korchagin, move the /crypto > fuzz target samples into a new /crypto/tests directory to separate > them from the functional source code. > - Per feedback from David Gow and Marco Elver, add the kfuzztest-bridge > tool to generate structured inputs for fuzz targets. The tool can > populate parts of the input structure with data from a file, enabling > both simple randomized fuzzing (e.g, using /dev/urandom) and > targeted testing with file-based inputs. > > We would like to thank David Gow for his detailed feedback regarding the > potential integration with KUnit. The v1 discussion highlighted three > potential paths: making KFuzzTests a special case of KUnit tests, sharing > implementation details in a common library, or keeping the frameworks > separate while ensuring API familiarity. > > Following a productive conversation with David, we are moving forward > with the third option for now. While tighter integration is an > attractive long-term goal, we believe the most practical first step is > to establish KFuzzTest as a valuable, standalone framework. This avoids > premature abstraction (e.g., creating a shared library with only one > user) and allows KFuzzTest's design to stabilize based on its specific > focus: fuzzing with complex, structured inputs. > Thanks, Ethan. I've had a bit of a play around with the kfuzztest-bridge tool, and it seems to work pretty well here. I'm definitely looking forward to trying out The only real feature I'd find useful would be to have a human-readable way of describing the data (as well as the structure), which could be useful when passing around reproducers, and could make it possible to hand-craft or adapt cases to work cross-architecture, if that's a future goal. But I don't think that it's worth holding up an initial version for. On the subject of architecture support, I don't see anything particularly x86_64-specific in here (or at least, nothing that couldn't be relatively easily fixed). While I don't think you need to support lots of architectures immediately, it'd be nice to use architecture-independant things (like the shared include/asm-generic/vmlinux.lds.h) where possible. And even if you're focusing on x86_64, supporting UML -- which is still x86 under-the-hood, but has its own linker scripts -- would be a nice bonus if it's easy. Other things, like supporting 32-bit or big-endian setups are nice-to-have, but definitely not worth spending too much time on immediately (though if we start using some of the formats/features here for KUnit, we'll want to support them). Finally, while I like the samples and documentation, I think it'd be nice to include a working example of using kfuzztest-bridge alongside the samples, even if it's something as simple as including a line like: ./kfuzztest-bridge "some_buffer { ptr[buf] len[buf, u64]}; buf { arr[u8, 128] };" "test_underflow_on_buffer" /dev/urandom Regardless, this is very neat, and I can't wait (with some apprehension) to see what it finds! Cheers, -- David