From: Ethan Graham <ethan.w.s.graham@gmail.com>
To: ethangraham@google.com, glider@google.com
Cc: andreyknvl@gmail.com, andy@kernel.org, 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, tarasmadan@google.com
Subject: [PATCH v1 06/10] kfuzztest: add KFuzzTest sample fuzz targets
Date: Tue, 16 Sep 2025 09:01:05 +0000 [thread overview]
Message-ID: <20250916090109.91132-7-ethan.w.s.graham@gmail.com> (raw)
In-Reply-To: <20250916090109.91132-1-ethan.w.s.graham@gmail.com>
From: Ethan Graham <ethangraham@google.com>
Add two simple fuzz target samples to demonstrate the KFuzzTest API and
provide basic self-tests for the framework.
These examples showcase how a developer can define a fuzz target using
the FUZZ_TEST(), constraint, and annotation macros, and serve as runtime
sanity checks for the core logic. For example, they test that
out-of-bounds memory accesses into poisoned padding regions are
correctly detected in a KASAN build.
These have been tested by writing syzkaller-generated inputs into their
debugfs 'input' files and verifying that the correct KASAN reports were
triggered.
Signed-off-by: Ethan Graham <ethangraham@google.com>
Acked-by: Alexander Potapenko <glider@google.com>
---
samples/Kconfig | 7 ++
samples/Makefile | 1 +
samples/kfuzztest/Makefile | 3 +
samples/kfuzztest/overflow_on_nested_buffer.c | 71 +++++++++++++++++++
samples/kfuzztest/underflow_on_buffer.c | 59 +++++++++++++++
5 files changed, 141 insertions(+)
create mode 100644 samples/kfuzztest/Makefile
create mode 100644 samples/kfuzztest/overflow_on_nested_buffer.c
create mode 100644 samples/kfuzztest/underflow_on_buffer.c
diff --git a/samples/Kconfig b/samples/Kconfig
index 6e072a5f1ed8..5209dd9d7a5c 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -320,6 +320,13 @@ config SAMPLE_HUNG_TASK
Reading these files with multiple processes triggers hung task
detection by holding locks for a long time (256 seconds).
+config SAMPLE_KFUZZTEST
+ bool "Build KFuzzTest sample targets"
+ depends on KFUZZTEST
+ help
+ Build KFuzzTest sample targets that serve as selftests for input
+ deserialization and inter-region redzone poisoning logic.
+
source "samples/rust/Kconfig"
source "samples/damon/Kconfig"
diff --git a/samples/Makefile b/samples/Makefile
index 07641e177bd8..3a0e7f744f44 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -44,4 +44,5 @@ obj-$(CONFIG_SAMPLE_DAMON_WSSE) += damon/
obj-$(CONFIG_SAMPLE_DAMON_PRCL) += damon/
obj-$(CONFIG_SAMPLE_DAMON_MTIER) += damon/
obj-$(CONFIG_SAMPLE_HUNG_TASK) += hung_task/
+obj-$(CONFIG_SAMPLE_KFUZZTEST) += kfuzztest/
obj-$(CONFIG_SAMPLE_TSM_MR) += tsm-mr/
diff --git a/samples/kfuzztest/Makefile b/samples/kfuzztest/Makefile
new file mode 100644
index 000000000000..4f8709876c9e
--- /dev/null
+++ b/samples/kfuzztest/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_SAMPLE_KFUZZTEST) += overflow_on_nested_buffer.o underflow_on_buffer.o
diff --git a/samples/kfuzztest/overflow_on_nested_buffer.c b/samples/kfuzztest/overflow_on_nested_buffer.c
new file mode 100644
index 000000000000..2f1c3ff9f750
--- /dev/null
+++ b/samples/kfuzztest/overflow_on_nested_buffer.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This file contains a KFuzzTest example target that ensures that a buffer
+ * overflow on a nested region triggers a KASAN OOB access report.
+ *
+ * Copyright 2025 Google LLC
+ */
+
+/**
+ * DOC: test_overflow_on_nested_buffer
+ *
+ * This test uses a struct with two distinct dynamically allocated buffers.
+ * It checks that KFuzzTest's memory layout correctly poisons the memory
+ * regions and that KASAN can detect an overflow when reading one byte past the
+ * end of the first buffer (`a`).
+ *
+ * It can be invoked with kfuzztest-bridge using the following command:
+ *
+ * ./kfuzztest-bridge \
+ * "nested_buffers { ptr[a] len[a, u64] ptr[b] len[b, u64] }; \
+ * a { arr[u8, 64] }; b { arr[u8, 64] };" \
+ * "test_overflow_on_nested_buffer" /dev/urandom
+ *
+ * The first argument describes the C struct `nested_buffers` and specifies that
+ * both `a` and `b` are pointers to arrays of 64 bytes.
+ */
+#include <linux/kfuzztest.h>
+
+static void overflow_on_nested_buffer(const char *a, size_t a_len, const char *b, size_t b_len)
+{
+ size_t i;
+ pr_info("a = [%px, %px)", a, a + a_len);
+ pr_info("b = [%px, %px)", b, b + b_len);
+
+ /* Ensure that all bytes in arg->b are accessible. */
+ for (i = 0; i < b_len; i++)
+ READ_ONCE(b[i]);
+ /*
+ * Check that all bytes in arg->a are accessible, and provoke an OOB on
+ * the first byte to the right of the buffer which will trigger a KASAN
+ * report.
+ */
+ for (i = 0; i <= a_len; i++)
+ READ_ONCE(a[i]);
+}
+
+struct nested_buffers {
+ const char *a;
+ size_t a_len;
+ const char *b;
+ size_t b_len;
+};
+
+/**
+ * The KFuzzTest input format specifies that struct nested buffers should
+ * be expanded as:
+ *
+ * | a | b | pad[8] | *a | pad[8] | *b |
+ *
+ * where the padded regions are poisoned. We expect to trigger a KASAN report by
+ * overflowing one byte into the `a` buffer.
+ */
+FUZZ_TEST(test_overflow_on_nested_buffer, struct nested_buffers)
+{
+ KFUZZTEST_EXPECT_NOT_NULL(nested_buffers, a);
+ KFUZZTEST_EXPECT_NOT_NULL(nested_buffers, b);
+ KFUZZTEST_ANNOTATE_LEN(nested_buffers, a_len, a);
+ KFUZZTEST_ANNOTATE_LEN(nested_buffers, b_len, b);
+
+ overflow_on_nested_buffer(arg->a, arg->a_len, arg->b, arg->b_len);
+}
diff --git a/samples/kfuzztest/underflow_on_buffer.c b/samples/kfuzztest/underflow_on_buffer.c
new file mode 100644
index 000000000000..02704a1bfebb
--- /dev/null
+++ b/samples/kfuzztest/underflow_on_buffer.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This file contains a KFuzzTest example target that ensures that a buffer
+ * underflow on a region triggers a KASAN OOB access report.
+ *
+ * Copyright 2025 Google LLC
+ */
+
+/**
+ * DOC: test_underflow_on_buffer
+ *
+ * This test ensures that the region between the metadata struct and the
+ * dynamically allocated buffer is poisoned. It provokes a one-byte underflow
+ * on the buffer, which should be caught by KASAN.
+ *
+ * It can be invoked with kfuzztest-bridge using the following command:
+ *
+ * ./kfuzztest-bridge \
+ * "some_buffer { ptr[buf] len[buf, u64]}; buf { arr[u8, 128] };" \
+ * "test_underflow_on_buffer" /dev/urandom
+ *
+ * The first argument describes the C struct `some_buffer` and specifies that
+ * `buf` is a pointer to an array of 128 bytes. The second argument is the test
+ * name, and the third is a seed file.
+ */
+#include <linux/kfuzztest.h>
+
+static void underflow_on_buffer(char *buf, size_t buflen)
+{
+ size_t i;
+
+ pr_info("buf = [%px, %px)", buf, buf + buflen);
+
+ /* First ensure that all bytes in arg->b are accessible. */
+ for (i = 0; i < buflen; i++)
+ READ_ONCE(buf[i]);
+ /*
+ * Provoke a buffer overflow on the first byte preceding b, triggering
+ * a KASAN report.
+ */
+ READ_ONCE(*((char *)buf - 1));
+}
+
+struct some_buffer {
+ char *buf;
+ size_t buflen;
+};
+
+/**
+ * Tests that the region between struct some_buffer and the expanded *buf field
+ * is correctly poisoned by accessing the first byte before *buf.
+ */
+FUZZ_TEST(test_underflow_on_buffer, struct some_buffer)
+{
+ KFUZZTEST_EXPECT_NOT_NULL(some_buffer, buf);
+ KFUZZTEST_ANNOTATE_LEN(some_buffer, buflen, buf);
+
+ underflow_on_buffer(arg->buf, arg->buflen);
+}
--
2.51.0.384.g4c02a37b29-goog
next prev parent reply other threads:[~2025-09-16 9:01 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-16 9:00 [PATCH v1 0/10] KFuzzTest: a new kernel fuzzing framework Ethan Graham
2025-09-16 9:01 ` [PATCH v1 01/10] mm/kasan: implement kasan_poison_range Ethan Graham
2025-09-16 9:34 ` Alexander Potapenko
2025-09-16 9:01 ` [PATCH v1 02/10] kfuzztest: add user-facing API and data structures Ethan Graham
2025-09-16 9:58 ` Alexander Potapenko
2025-09-16 9:01 ` [PATCH v1 03/10] kfuzztest: implement core module and input processing Ethan Graham
2025-09-16 10:21 ` Alexander Potapenko
2025-09-17 3:59 ` kernel test robot
2025-09-18 1:21 ` kernel test robot
2025-09-16 9:01 ` [PATCH v1 04/10] tools: add kfuzztest-bridge utility Ethan Graham
2025-09-16 13:42 ` Alexander Potapenko
2025-09-17 13:26 ` SeongJae Park
2025-09-16 9:01 ` [PATCH v1 05/10] kfuzztest: add ReST documentation Ethan Graham
2025-09-16 9:01 ` Ethan Graham [this message]
2025-09-18 3:17 ` [PATCH v1 06/10] kfuzztest: add KFuzzTest sample fuzz targets kernel test robot
2025-09-16 9:01 ` [PATCH v1 07/10] crypto: implement KFuzzTest targets for PKCS7 and RSA parsing Ethan Graham
2025-09-16 10:28 ` Ignat Korchagin
2025-09-17 23:37 ` kernel test robot
2025-09-18 6:52 ` kernel test robot
2025-09-18 14:15 ` Alexander Potapenko
2025-09-16 9:01 ` [PATCH v1 08/10] drivers/auxdisplay: add a KFuzzTest for parse_xy() Ethan Graham
2025-09-16 9:01 ` [PATCH v1 09/10] fs/binfmt_script: add KFuzzTest target for load_script Ethan Graham
2025-09-17 5:04 ` kernel test robot
2025-09-16 9:01 ` [PATCH v1 10/10] MAINTAINERS: add maintainer information for KFuzzTest Ethan Graham
2025-09-16 9:38 ` Alexander Potapenko
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=20250916090109.91132-7-ethan.w.s.graham@gmail.com \
--to=ethan.w.s.graham@gmail.com \
--cc=andreyknvl@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=ethangraham@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=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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.