From: Ethan Graham <ethan.w.s.graham@gmail.com>
To: ethan.w.s.graham@gmail.com, glider@google.com
Cc: andreyknvl@gmail.com, andy@kernel.org, andy.shevchenko@gmail.com,
brauner@kernel.org, brendan.higgins@linux.dev,
davem@davemloft.net, davidgow@google.com, dhowells@redhat.com,
dvyukov@google.com, elver@google.com,
herbert@gondor.apana.org.au, ignat@cloudflare.com, jack@suse.cz,
jannh@google.com, johannes@sipsolutions.net,
kasan-dev@googlegroups.com, kees@kernel.org,
kunit-dev@googlegroups.com, linux-crypto@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
lukas@wunner.de, rmoar@google.com, shuah@kernel.org,
sj@kernel.org, tarasmadan@google.com
Subject: [PATCH 03/10] kfuzztest: introduce the FUZZ_TEST_SIMPLE macro
Date: Thu, 4 Dec 2025 15:12:42 +0100 [thread overview]
Message-ID: <20251204141250.21114-4-ethan.w.s.graham@gmail.com> (raw)
In-Reply-To: <20251204141250.21114-1-ethan.w.s.graham@gmail.com>
The serialization format required by a KFuzzTest target defined with the
FUZZ_TEST macro is overkill for simpler cases, in particular the very
common pattern of kernel interfaces taking a (data, datalen) pair.
Introduce the FUZZ_TEST_SIMPLE for defining simple targets that accept
a simpler binary interface without any required serialization. The aim
is to make simple targets compatible with a wide variety of userspace
fuzzing engines out of the box.
A FUZZ_TEST_SIMPLE target also defines an equivalent FUZZ_TEST macro in
its expansion maintaining compatibility with the default KFuzzTest
interface, using a shared `struct kfuzztest_simple_arg` as input type.
In essence, the following equivalence holds:
FUZZ_TEST_SIMPLE(test) === FUZZ_TEST(test, struct kfuzztest_simple_arg)
Constraints and annotation metadata for `struct kfuzztest_simple_arg` is
defined statically in the header file to avoid duplicate definitions in
the compiled vmlinux image.
Signed-off-by: Ethan Graham <ethan.w.s.graham@gmail.com>
---
include/asm-generic/vmlinux.lds.h | 4 ++
include/linux/kfuzztest.h | 87 +++++++++++++++++++++++++++++++
2 files changed, 91 insertions(+)
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 9afe569d013b..2736dd41fba0 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -974,6 +974,10 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
KEEP(*(.kfuzztest_target)); \
__kfuzztest_targets_end = .; \
. = ALIGN(PAGE_SIZE); \
+ __kfuzztest_simple_targets_start = .; \
+ KEEP(*(.kfuzztest_simple_target)); \
+ __kfuzztest_simple_targets_end = .; \
+ . = ALIGN(PAGE_SIZE); \
__kfuzztest_constraints_start = .; \
KEEP(*(.kfuzztest_constraint)); \
__kfuzztest_constraints_end = .; \
diff --git a/include/linux/kfuzztest.h b/include/linux/kfuzztest.h
index 1839fcfeabf5..284142fa4300 100644
--- a/include/linux/kfuzztest.h
+++ b/include/linux/kfuzztest.h
@@ -483,4 +483,91 @@ fail_early: \
} \
static void kfuzztest_logic_##test_name(test_arg_type *arg)
+struct kfuzztest_simple_target {
+ const char *name;
+ ssize_t (*write_input_cb)(struct file *filp, const char __user *buf, size_t len, loff_t *off);
+} __aligned(32);
+
+struct kfuzztest_simple_arg {
+ char *data;
+ size_t datalen;
+};
+
+/* Define constraint and annotation metadata for reused kfuzztest_simple_arg. */
+__KFUZZTEST_CONSTRAINT(kfuzztest_simple_arg, data, NULL, 0x0, EXPECT_NE);
+__KFUZZTEST_ANNOTATE(kfuzztest_simple_arg, data, NULL, ATTRIBUTE_ARRAY);
+__KFUZZTEST_ANNOTATE(kfuzztest_simple_arg, datalen, data, ATTRIBUTE_LEN);
+
+/**
+ * FUZZ_TEST_SIMPLE - defines a simple KFuzzTest target
+ *
+ * @test_name: the unique identifier for the fuzz test, which is used to name
+ * the debugfs entry.
+ *
+ * This macro function nearly identically to the standard FUZZ_TEST target, the
+ * key difference being that a simple fuzz target is constrained to inputs of
+ * the form `(char *data, size_t datalen)` - a common pattern in kernel APIs.
+ *
+ * The FUZZ_TEST_SIMPLE macro expands to define an equivalent FUZZ_TEST,
+ * effectively creating two debugfs input files for the fuzz target. In essence,
+ * on top of creating an input file under kfuzztest/@test_name/input, a new
+ * simple input file is created under kfuzztest/@test_name/input_simple. This
+ * debugfs file takes raw byte buffers as input and doesn't require any special
+ * serialization.
+ *
+ * User-provided Logic:
+ * The developer must provide the body of the fuzz test logic within the curly
+ * braces following the macro invocation. Within this scope, the framework
+ * provides the `data` and `datalen` variables, where `datalen == len(data)`.
+ *
+ * Example Usage:
+ *
+ * // 1. The kernel function that we wnat to fuzz.
+ * int process_data(const char *data, size_t datalen);
+ *
+ * // 2. Define a fuzz target using the FUZZ_TEST_SIMPLE macro.
+ * FUZZ_TEST_SIMPLE(test_process_data)
+ * {
+ * // Call the function under test using the `data` and `datalen`
+ * // variables.
+ * process_data(data, datalen);
+ * }
+ *
+ */
+#define FUZZ_TEST_SIMPLE(test_name) \
+ static ssize_t kfuzztest_simple_write_cb_##test_name(struct file *filp, const char __user *buf, size_t len, \
+ loff_t *off); \
+ static void kfuzztest_simple_logic_##test_name(char *data, size_t datalen); \
+ static const struct kfuzztest_simple_target __fuzz_test_simple__##test_name __section( \
+ ".kfuzztest_simple_target") __used = { \
+ .name = #test_name, \
+ .write_input_cb = kfuzztest_simple_write_cb_##test_name, \
+ }; \
+ FUZZ_TEST(test_name, struct kfuzztest_simple_arg) \
+ { \
+ /* We don't use the KFUZZTEST_EXPECT macro to define the
+ * non-null constraint on `arg->data` as we only want metadata
+ * to be emitted once, so we enforce it here manually. */ \
+ if (arg->data == NULL) \
+ return; \
+ kfuzztest_simple_logic_##test_name(arg->data, arg->datalen); \
+ } \
+ static ssize_t kfuzztest_simple_write_cb_##test_name(struct file *filp, const char __user *buf, size_t len, \
+ loff_t *off) \
+ { \
+ void *buffer; \
+ int ret; \
+ \
+ ret = kfuzztest_write_cb_common(filp, buf, len, off, &buffer); \
+ if (ret < 0) \
+ goto out; \
+ kfuzztest_simple_logic_##test_name(buffer, len); \
+ record_invocation(); \
+ ret = len; \
+ kfree(buffer); \
+out: \
+ return ret; \
+ } \
+ static void kfuzztest_simple_logic_##test_name(char *data, size_t datalen)
+
#endif /* KFUZZTEST_H */
--
2.51.0
next prev parent reply other threads:[~2025-12-04 14:13 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-04 14:12 [PATCH v3 00/10] KFuzzTest: a new kernel fuzzing framework Ethan Graham
2025-12-04 14:12 ` [PATCH 01/10] mm/kasan: implement kasan_poison_range Ethan Graham
2025-12-04 15:17 ` Andrey Konovalov
2025-12-04 15:31 ` Andy Shevchenko
2025-12-04 14:12 ` [PATCH 02/10] kfuzztest: add user-facing API and data structures Ethan Graham
2025-12-04 14:12 ` Ethan Graham [this message]
2025-12-04 14:12 ` [PATCH 04/10] kfuzztest: implement core module and input processing Ethan Graham
2025-12-04 14:12 ` [PATCH 05/10] tools: add kfuzztest-bridge utility Ethan Graham
2025-12-07 6:38 ` kernel test robot
2025-12-04 14:12 ` [PATCH 06/10] kfuzztest: add ReST documentation Ethan Graham
2025-12-04 14:12 ` [PATCH 07/10] kfuzztest: add KFuzzTest sample fuzz targets Ethan Graham
2025-12-04 14:12 ` [PATCH 08/10] crypto: implement KFuzzTest targets for PKCS7 and RSA parsing Ethan Graham
2025-12-04 14:12 ` [PATCH 09/10] drivers/auxdisplay: add a KFuzzTest for parse_xy() Ethan Graham
2025-12-04 15:26 ` Andy Shevchenko
2025-12-04 15:28 ` Andy Shevchenko
2025-12-04 15:32 ` Marco Elver
2025-12-04 15:34 ` Andy Shevchenko
2025-12-04 15:35 ` Marco Elver
2025-12-04 15:42 ` Marco Elver
2025-12-04 15:56 ` Greg Kroah-Hartman
2025-12-04 17:10 ` Andy Shevchenko
2025-12-04 21:38 ` Ethan Graham
2025-12-08 0:58 ` kernel test robot
2025-12-04 14:12 ` [PATCH 10/10] MAINTAINERS: add maintainer information for KFuzzTest Ethan Graham
2025-12-12 8:01 ` [PATCH v3 00/10] KFuzzTest: a new kernel fuzzing framework Luis Chamberlain
2025-12-12 15:09 ` Andy Shevchenko
2025-12-13 0:06 ` Shuah Khan
2025-12-17 9:53 ` David Gow
2025-12-17 10:19 ` Alexander Potapenko
2025-12-17 10:31 ` Johannes Berg
2025-12-17 1:08 ` Wentao Zhang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251204141250.21114-4-ethan.w.s.graham@gmail.com \
--to=ethan.w.s.graham@gmail.com \
--cc=andreyknvl@gmail.com \
--cc=andy.shevchenko@gmail.com \
--cc=andy@kernel.org \
--cc=brauner@kernel.org \
--cc=brendan.higgins@linux.dev \
--cc=davem@davemloft.net \
--cc=davidgow@google.com \
--cc=dhowells@redhat.com \
--cc=dvyukov@google.com \
--cc=elver@google.com \
--cc=glider@google.com \
--cc=herbert@gondor.apana.org.au \
--cc=ignat@cloudflare.com \
--cc=jack@suse.cz \
--cc=jannh@google.com \
--cc=johannes@sipsolutions.net \
--cc=kasan-dev@googlegroups.com \
--cc=kees@kernel.org \
--cc=kunit-dev@googlegroups.com \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=lukas@wunner.de \
--cc=rmoar@google.com \
--cc=shuah@kernel.org \
--cc=sj@kernel.org \
--cc=tarasmadan@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®