lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260112192827.25989-2-ethan.w.s.graham@gmail.com>
Date: Mon, 12 Jan 2026 20:28:22 +0100
From: Ethan Graham <ethan.w.s.graham@...il.com>
To: ethan.w.s.graham@...il.com,
	glider@...gle.com
Cc: akpm@...ux-foundation.org,
	andreyknvl@...il.com,
	andy@...nel.org,
	andy.shevchenko@...il.com,
	brauner@...nel.org,
	brendan.higgins@...ux.dev,
	davem@...emloft.net,
	davidgow@...gle.com,
	dhowells@...hat.com,
	dvyukov@...gle.com,
	ebiggers@...nel.org,
	elver@...gle.com,
	gregkh@...uxfoundation.org,
	herbert@...dor.apana.org.au,
	ignat@...udflare.com,
	jack@...e.cz,
	jannh@...gle.com,
	johannes@...solutions.net,
	kasan-dev@...glegroups.com,
	kees@...nel.org,
	kunit-dev@...glegroups.com,
	linux-crypto@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	linux-mm@...ck.org,
	lukas@...ner.de,
	mcgrof@...nel.org,
	rmoar@...gle.com,
	shuah@...nel.org,
	sj@...nel.org,
	skhan@...uxfoundation.org,
	tarasmadan@...gle.com,
	wentaoz5@...inois.edu
Subject: [PATCH v4 1/6] kfuzztest: add user-facing API and data structures

Add the foundational user-facing components for the KFuzzTest framework.
This includes the main API header <linux/kfuzztest.h>, the Kconfig
option to enable the feature, and the required linker script changes
which introduce a new ELF section in vmlinux.

Note that KFuzzTest is intended strictly for debug builds only, and
should never be enabled in a production build. The fact that it exposes
internal kernel functions and state directly to userspace may constitute
a serious security vulnerability if used for any reason other than
testing.

The header defines:
- The FUZZ_TEST_SIMPLE() macro for creating test targets.
- The `struct kfuzztest_simple_target` structure used to register tests.
- The linker section (.kfuzztest_simple_target) where test metadata is
  stored for discovery by the framework.

This patch only adds the public interface and build integration; no
runtime logic is included.

Signed-off-by: Ethan Graham <ethan.w.s.graham@...il.com>

---
PR v4:
- Remove the complex FUZZ_TEST macro and associated dependencies,
  including domain constraints, annotations, and de-serialization,
  dramatically simplifying the flow.
- Drop unused ELF sections (.kfuzztest_constraint, etc...) from the
  linker script, keeping only .kfuzztest_simple_target.
PR v3:
- Reorder definitions in kfuzztest.h for better flow and readability.
- Introduce __KFUZZTEST_CONSTRAINT macro in preparation for the
  introduction of the FUZZ_TEST_SIMPLE macro in the following patch,
  which uses it for manually emitting constraint metadata.
PR v1:
- Move KFuzzTest metadata definitions to generic vmlinux linkage so that
  the framework isn't bound to x86_64.
- Return -EFAULT when simple_write_to_buffer returns a value not equal
  to the input length in the main FUZZ_TEST macro.
- Enforce a maximum input size of 64KiB in the main FUZZ_TEST macro,
  returning -EINVAL when it isn't respected.
- Refactor KFUZZTEST_ANNOTATION_* macros.
- Taint the kernel with TAINT_TEST inside the FUZZ_TEST macro when a
  fuzz target is invoked for the first time.
---
---
 include/asm-generic/vmlinux.lds.h | 14 ++++-
 include/linux/kfuzztest.h         | 88 +++++++++++++++++++++++++++++++
 lib/Kconfig.debug                 |  1 +
 lib/kfuzztest/Kconfig             | 16 ++++++
 4 files changed, 118 insertions(+), 1 deletion(-)
 create mode 100644 include/linux/kfuzztest.h
 create mode 100644 lib/kfuzztest/Kconfig

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index ae2d2359b79e..5aa46dbbc9b2 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -373,7 +373,8 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
 	TRACE_PRINTKS()							\
 	BPF_RAW_TP()							\
 	TRACEPOINT_STR()						\
-	KUNIT_TABLE()
+	KUNIT_TABLE()							\
+	KFUZZTEST_TABLE()
 
 /*
  * Data section helpers
@@ -966,6 +967,17 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
 		BOUNDED_SECTION_POST_LABEL(.kunit_init_test_suites, \
 				__kunit_init_suites, _start, _end)
 
+#ifdef CONFIG_KFUZZTEST
+#define KFUZZTEST_TABLE()						\
+	. = ALIGN(PAGE_SIZE);						\
+	__kfuzztest_simple_targets_start = .;				\
+	KEEP(*(.kfuzztest_simple_target));				\
+	__kfuzztest_simple_targets_end = .;				\
+
+#else /* CONFIG_KFUZZTEST */
+#define KFUZZTEST_TABLE()
+#endif /* CONFIG_KFUZZTEST */
+
 #ifdef CONFIG_BLK_DEV_INITRD
 #define INIT_RAM_FS							\
 	. = ALIGN(4);							\
diff --git a/include/linux/kfuzztest.h b/include/linux/kfuzztest.h
new file mode 100644
index 000000000000..62fce9267761
--- /dev/null
+++ b/include/linux/kfuzztest.h
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Kernel Fuzz Testing Framework (KFuzzTest) API for defining fuzz targets
+ * for internal kernel functions.
+ *
+ * Copyright 2025 Google LLC
+ */
+#ifndef KFUZZTEST_H
+#define KFUZZTEST_H
+
+#include <linux/fs.h>
+#include <linux/printk.h>
+#include <linux/types.h>
+
+#define KFUZZTEST_MAX_INPUT_SIZE (PAGE_SIZE * 16)
+
+/* Common code for receiving inputs from userspace. */
+int kfuzztest_write_cb_common(struct file *filp, const char __user *buf, size_t len, loff_t *off, void **test_buffer);
+
+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);
+};
+
+/**
+ * FUZZ_TEST_SIMPLE - defines a KFuzzTest target
+ *
+ * @test_name: the unique identifier for the fuzz test, which is used to name
+ *             the debugfs entry.
+ *
+ * This macro defines a fuzz target entry point that accepts raw byte buffers
+ * from userspace. It registers a struct kfuzztest_simple_target which the
+ * framework exposes via debugfs.
+ *
+ * When userspace writes to the corresponding debugfs file, the framework
+ * allocates a kernel buffer, copies the user data, and passes it to the
+ * logic defined in the macro body.
+ *
+ * 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
+ * implicitly defines the following variables:
+ *
+ * - `char *data`: A pointer to the raw input data.
+ * - `size_t datalen`: The length of the input data.
+ *
+ * Example Usage:
+ *
+ * // 1. The kernel function that we want 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 ssize_t 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,						\
+	};														\
+	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;											\
+		ret = kfuzztest_simple_logic_##test_name(buffer, len);							\
+		if (ret == 0)												\
+			ret = len;											\
+		kfree(buffer);												\
+out:															\
+		return ret;												\
+	}														\
+	static ssize_t kfuzztest_simple_logic_##test_name(char *data, size_t datalen)
+
+#endif /* KFUZZTEST_H */
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index dc0e0c6ed075..49a1748b9f24 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1947,6 +1947,7 @@ endmenu
 menu "Kernel Testing and Coverage"
 
 source "lib/kunit/Kconfig"
+source "lib/kfuzztest/Kconfig"
 
 config NOTIFIER_ERROR_INJECTION
 	tristate "Notifier error injection"
diff --git a/lib/kfuzztest/Kconfig b/lib/kfuzztest/Kconfig
new file mode 100644
index 000000000000..d8e9caaac108
--- /dev/null
+++ b/lib/kfuzztest/Kconfig
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config KFUZZTEST
+	bool "KFuzzTest - enable support for internal fuzz targets"
+	depends on DEBUG_FS && DEBUG_KERNEL
+	help
+	  Enables support for the kernel fuzz testing framework (KFuzzTest), an
+	  interface for exposing internal kernel functions to a userspace fuzzing
+	  engine. KFuzzTest targets are exposed via a debugfs interface that
+	  accepts raw binary inputs from userspace, and is designed to make it
+	  easier to fuzz deeply nested kernel code that is hard to reach from
+	  the system call boundary. Using a simple macro-based API, developers
+	  can add a new fuzz target with minimal boilerplate code.
+
+	  WARNING: This exposes internal kernel functions directly to userspace
+	  and must NEVER be enabled in production builds.
-- 
2.51.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ