From nobody Sat Feb 7 08:22:57 2026 Received: from mail-ed1-f52.google.com (mail-ed1-f52.google.com [209.85.208.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 416BB2FF65B for ; Mon, 12 Jan 2026 19:28:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768246125; cv=none; b=fGtA6Bfsh3QgDImvQyuFYMEg9Y4rmmp9xMP7OP4fM085QUGhD7GiGQnYHscraakasG65Mle/ASU/kwhQAZ6gAVHkfleZFimxGETcTRcIf1IyGw1gL8Smdgi9HvB1y163WqP1tZjH9tTtJTh4976evpCPVJpAvJL8oqnCxWKcgik= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768246125; c=relaxed/simple; bh=RfNOTU1rUXZFy81KWIMuzlRH+1v6cHn4VlKbisbvBZo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QD180ImaPFCS1R95jpACYTYNPVNgNnM7haREoxfBSg4LLs8az3QwUREO1m7vZvfVkc5pYMGdXhAMi/dkhBnZAnO8Uyjmo1GsNe6nGwCW5v/XT4zzrM08jwufIXEzwwDTDMh0yi6DJz/CNAdvRbhubvaTfODXAqXYEL8JRaQt5qM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=G0FD+77D; arc=none smtp.client-ip=209.85.208.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="G0FD+77D" Received: by mail-ed1-f52.google.com with SMTP id 4fb4d7f45d1cf-64d0d41404cso11108427a12.0 for ; Mon, 12 Jan 2026 11:28:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768246122; x=1768850922; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=F6pmlmleIFnHYbLcLeHzqqQV2depV+HvaEyub6pwhNU=; b=G0FD+77D2bNI93Aqfu3A9WVv9s0XQFwPwdbqoWyGxsrZlA92ckAmnrpJ6H1j9RmZNA Z8Sl73GHmSUaNcv2fDUUGiY1+Zq4658rfZebBt8M2O8MCHhr1OptyqRbmoI7NtUsu1Bb DP6QfCQRQAvz2su1IRRU0B/wdAbCR0ggKILjwhVBYDSPma3RX1saC6kL4eZIVQPlzUSQ JrYQVUr+CWPTnIssy7UoA80Hy0aPeZOQnr6rd7GmpoREVaDMr3fTGAVSxYz57Wii1qc6 ZsSXys7YoBUMkKwkyOd0A+oNHdMhvikQyC2qbG2H1mXrTDio3/vXENnWXmzbCB7Wt/yl 9emw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768246122; x=1768850922; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=F6pmlmleIFnHYbLcLeHzqqQV2depV+HvaEyub6pwhNU=; b=dq7ysmJqvTGynSuJ+pLdGKwMPweFKRV0BNnlic39ONtbJcJxxT7ERYxg7eGJyZDQoM b4TJzf0UKFVyzbgNwP9PVH02y9ZAab4BDvVW63zMJ/p807EPSjRGeqFNFF41uZcfCqnI qdWUt/drsJFaupHrFzQvlwcRs9+yIi5O7T7iYFRvsqr0R8JSwIpITcl0XDYwa0lqnRKU jmRiLBtbBbi3+cECk2PsMe3hc5NcwCFkrWJzjzqXS5yDMgwoKZB6FG7YvgRfTHnaJUPc 1MTbqLTXwUYJkStMldFeLAv79IV6MFx9lEapPhXqQNegT1NCdsbTjkad3UIfqfi6svkm laAA== X-Forwarded-Encrypted: i=1; AJvYcCUb8CkNpsWTXOJivVAgx9fNObsKRTq6j5JQLTKNv82xWaDHwVpFwokxJDhn8vWKhnyrd9jC1JU2DrhLgbk=@vger.kernel.org X-Gm-Message-State: AOJu0Yz/aVwvGJxwzf2R0aITsTHtoBhJ9Sh4VSLDNuLJnjpWy6w2a03R zDOCu54rwQFCg35em4FM0w2SonSmV0FCm98X7+2ZrmOJbJniKWLuAGbl X-Gm-Gg: AY/fxX56BpU5OdhJH2cnESX0M4QFAh0om1f99wcBWfVuqVZIB37b8MwLxxk0E9PRgcT uFhcINLrU2nXpCkpF9SHgXt0XYtrAogcQgz8BJe+I89VwbM97UuzqRFjoZ4nFggAIFg5bG+Cg3b Wv6wT9uK9oJ5IWYPJxdCZokjtR5F7zDFUqojX8Fbrdm5vxdCD3Elh1XIwpiuIAgW6me8SPxYtHH kKH08DYkULo7JQvpzIcfp4mPFlw/99c9wDaXzUqHPELoudBXNDdY3Q9XVSWCrwN7mWmw0zaO2NP 3tnOnqZN9l0LKYQwgiPvlYK59x3MyU7mgBfQGMu344TBcAvOmGc/Edgmt/AdFnB0DfnXa8ElQLp KsDEqnri9w4dxtoZEFFT4/sYbI9YpyoEWidNsNQUZw/ul65h32Aen5EUMemGAAJd5lNcYKJUWgy /lhO1hvqHGySdXtfJ5xLpQ+qU0LHx0veC7XFxaVvkmV6PJnzOAew== X-Google-Smtp-Source: AGHT+IGy522OXBlgiFW3lPd749jJAYgvouP4QS9c8yndvmWTKnryLyWxg/YRj13+vMvBUdmHcTA0tA== X-Received: by 2002:a05:6402:42d3:b0:64b:6dfc:dd34 with SMTP id 4fb4d7f45d1cf-65097cde534mr16779217a12.0.1768246121349; Mon, 12 Jan 2026 11:28:41 -0800 (PST) Received: from ethan-tp (xdsl-31-164-106-179.adslplus.ch. [31.164.106.179]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6507bf667fcsm18108959a12.29.2026.01.12.11.28.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Jan 2026 11:28:40 -0800 (PST) From: Ethan Graham To: ethan.w.s.graham@gmail.com, glider@google.com Cc: akpm@linux-foundation.org, 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, ebiggers@kernel.org, elver@google.com, gregkh@linuxfoundation.org, 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, mcgrof@kernel.org, rmoar@google.com, shuah@kernel.org, sj@kernel.org, skhan@linuxfoundation.org, tarasmadan@google.com, wentaoz5@illinois.edu Subject: [PATCH v4 1/6] kfuzztest: add user-facing API and data structures Date: Mon, 12 Jan 2026 20:28:22 +0100 Message-ID: <20260112192827.25989-2-ethan.w.s.graham@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260112192827.25989-1-ethan.w.s.graham@gmail.com> References: <20260112192827.25989-1-ethan.w.s.graham@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add the foundational user-facing components for the KFuzzTest framework. This includes the main API header , 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 --- 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/vmlinu= x.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_PROPELL= ER_CLANG) TRACE_PRINTKS() \ BPF_RAW_TP() \ TRACEPOINT_STR() \ - KUNIT_TABLE() + KUNIT_TABLE() \ + KFUZZTEST_TABLE() =20 /* * Data section helpers @@ -966,6 +967,17 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPEL= LER_CLANG) BOUNDED_SECTION_POST_LABEL(.kunit_init_test_suites, \ __kunit_init_suites, _start, _end) =20 +#ifdef CONFIG_KFUZZTEST +#define KFUZZTEST_TABLE() \ + . =3D ALIGN(PAGE_SIZE); \ + __kfuzztest_simple_targets_start =3D .; \ + KEEP(*(.kfuzztest_simple_target)); \ + __kfuzztest_simple_targets_end =3D .; \ + +#else /* CONFIG_KFUZZTEST */ +#define KFUZZTEST_TABLE() +#endif /* CONFIG_KFUZZTEST */ + #ifdef CONFIG_BLK_DEV_INITRD #define INIT_RAM_FS \ . =3D 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 tar= gets + * for internal kernel functions. + * + * Copyright 2025 Google LLC + */ +#ifndef KFUZZTEST_H +#define KFUZZTEST_H + +#include +#include +#include + +#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, s= ize_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 n= ame + * the debugfs entry. + * + * This macro defines a fuzz target entry point that accepts raw byte buff= ers + * 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 c= urly + * 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, c= onst char __user *buf, size_t len, \ + loff_t *off); \ + static ssize_t kfuzztest_simple_logic_##test_name(char *data, size_t data= len); \ + static const struct kfuzztest_simple_target __fuzz_test_simple__##test_na= me __section( \ + ".kfuzztest_simple_target") __used =3D { \ + .name =3D #test_name, \ + .write_input_cb =3D kfuzztest_simple_write_cb_##test_name, \ + }; \ + static ssize_t kfuzztest_simple_write_cb_##test_name(struct file *filp, c= onst char __user *buf, size_t len, \ + loff_t *off) \ + { \ + void *buffer; \ + int ret; \ + \ + ret =3D kfuzztest_write_cb_common(filp, buf, len, off, &buffer); \ + if (ret < 0) \ + goto out; \ + ret =3D kfuzztest_simple_logic_##test_name(buffer, len); \ + if (ret =3D=3D 0) \ + ret =3D len; \ + kfree(buffer); \ +out: \ + return ret; \ + } \ + static ssize_t kfuzztest_simple_logic_##test_name(char *data, size_t data= len) + +#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" =20 source "lib/kunit/Kconfig" +source "lib/kfuzztest/Kconfig" =20 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. --=20 2.51.0 From nobody Sat Feb 7 08:22:57 2026 Received: from mail-ed1-f41.google.com (mail-ed1-f41.google.com [209.85.208.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E55A0320A02 for ; Mon, 12 Jan 2026 19:28:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768246126; cv=none; b=NVu9btU53JVh3rrIcp/F+BXFDGF6mMl4ADSfJVUnWWtvufXy0IoiPinb6frdfG9OrEw59IopNRR3fzEtuVY2vR5axefPWg78teMklidyb0f9fJ04yP692j/Y0ZCFlMnoZv5y43eMj6Bgu73jzb7Dv93JOE5KtTbqX08BXXE5mdk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768246126; c=relaxed/simple; bh=cF1SrwFUz0aBiEwsFE0dTWI91lmrP4xlRA143q9JWuM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lfrgicd7Sv4MfHFxcdrdJe5c4lyZrkhZ3EoqkW6uPWXEBwp/cJ4I/2uzWcAJru8TYI3wgqQ205Zcz0v+X7ca7x5amfPdJPMmixobRtyAjhChHxkUenyKci3gv9InTB8GaGIb6m4kvy54CMu+rH98lQ/FEMBhuwwJtIo2QMqB+Nk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=l3Jte956; arc=none smtp.client-ip=209.85.208.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="l3Jte956" Received: by mail-ed1-f41.google.com with SMTP id 4fb4d7f45d1cf-64baaa754c6so9689551a12.3 for ; Mon, 12 Jan 2026 11:28:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768246123; x=1768850923; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Hw+SyBhpJj8Dk0rbLbmvCfZKQJWCvJPz8EnXuKWjIzw=; b=l3Jte956WVCyRw/GXg2tGdpUIQzjoG5cMeo+qKSZWIZAuhqBO7ySzM1vhS94ULxwTH iNIZWssXZ1DUBfRdUt0WLov+boooCDx6eyEH1buYUAnX0gr0inZCgCo2SaHGbuh5mzcK HVbjQUUYxdzvodJ5VXqR4XBrs5TPfoHCYViCjQeKM/jsSMgrPbhJcvaWHkEmx9hHzbSg Fh8dVx+LblUhypobh5kKXCIdLk3+BNcNeDePRXsVM4Dw+RC4ORhAM2GamgHQgdTWwaLo VkWDC1BI4e9XolJJhZaBD855RkOm6qDsvKiNd7efciVvL9sVjtlo9gEXYmOteQG1lj6r 880w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768246123; x=1768850923; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Hw+SyBhpJj8Dk0rbLbmvCfZKQJWCvJPz8EnXuKWjIzw=; b=Tpu5p3nqLmekzEBZ0r5BPziD9PK6zQXxJSQZ7n9jS+t/IrcVkVJApaI83WtRdGZkNR zzT5iXPFF+7cSpI6M9dimf2YPod8wJxEHTfHofg3xDdeTO+zOPkDpyPzgwzF2hOC/nM1 SNRkaUv9iiP8Ig55yS5xBtA6KuZ+gIvidYf2ppQmv48nP147zE3WQttAQQ3R/WhbhV1l Njy84S6rhtvK5auBLWU//YX4JZuml36k7Y7zA7JI4umTJvgGuc7AO9xfcs3Z7FE1aOev fFPz9IyLAsGIM52wk9CU6F6cPaFGnaugc8zL5vklVfhuOlRugqIO5F4i4nOgBCfjZCzb CaLw== X-Forwarded-Encrypted: i=1; AJvYcCU2TjFKaevlpJsWMPtyzMGDUA+VIJFciEPf/NTNOAKH8kj/7xW52dgNX0TqGVCfyIdVWM9UJ6qj+xkjGVI=@vger.kernel.org X-Gm-Message-State: AOJu0YxxgKnfqKy2NUyDECClSrcQwhD6ao7y6sH8A74zsBMnNqiAlmHm qOOgrjg6Pv20cLM7l6LeFBy7sUlOQIFjffRxZPA32ZluVfl6H3E37pEV X-Gm-Gg: AY/fxX7aZhDFVL8xHvobTC7Lkm2jeZXgvN4UkzwyR/UIzHRnFUmF9/f5IWJHbaXdexZ fjgWMDG7YwCtTonIJW77kwQ5zJMEn0AvNaSI5YIS0cjt9w4v0IXwnNWztdErlJHfR4iWqmttMXK A2tsGfIsJmzmJiWDz1ndgGOpRAqsjHiVVsvYxZNYjErM/hhrvE4OG4B97ZKJRfwTORNoh3ZW1OG BgCmZysJlWhPDft5B02APqFLkT7MpdUKPRIJlilRYRTCl89iwuD/BBx42Wt4j2vNKZW+lgU4eym 7RCJ4j+7mL7P4Ke4SqoR9iOqTFNmLBVRl/LCFduV/Z1ZpufnxKVfAufn6Qf9p4JIcMkmHARvCB+ zRrjZ0YvSw0x+WO0KyK3bPfWu8pdz2bN3xDEb3fodyoXGdbFsKbtb2pdlno1YZ7gpomkxkdjqum DQd6ASpd/y/vldiJbVYydaKAtXyyOvgGD6mPSeypq4PdEEFpOI9Q== X-Google-Smtp-Source: AGHT+IFpEfk67Wu3s+my7vAAjgYzI8tk25YBO54kBfzlkDE0wM0gQSWTlCzqTfS+7VeyIp6Wy6teeA== X-Received: by 2002:a05:6402:1e8c:b0:64b:6007:d8dc with SMTP id 4fb4d7f45d1cf-65097dcd890mr17558013a12.7.1768246122989; Mon, 12 Jan 2026 11:28:42 -0800 (PST) Received: from ethan-tp (xdsl-31-164-106-179.adslplus.ch. [31.164.106.179]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6507bf667fcsm18108959a12.29.2026.01.12.11.28.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Jan 2026 11:28:42 -0800 (PST) From: Ethan Graham To: ethan.w.s.graham@gmail.com, glider@google.com Cc: akpm@linux-foundation.org, 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, ebiggers@kernel.org, elver@google.com, gregkh@linuxfoundation.org, 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, mcgrof@kernel.org, rmoar@google.com, shuah@kernel.org, sj@kernel.org, skhan@linuxfoundation.org, tarasmadan@google.com, wentaoz5@illinois.edu Subject: [PATCH v4 2/6] kfuzztest: implement core module and input processing Date: Mon, 12 Jan 2026 20:28:23 +0100 Message-ID: <20260112192827.25989-3-ethan.w.s.graham@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260112192827.25989-1-ethan.w.s.graham@gmail.com> References: <20260112192827.25989-1-ethan.w.s.graham@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add the core runtime implementation for KFuzzTest. This includes the module initialization, and the logic for receiving and processing user-provided inputs through debugfs. On module load, the framework discovers all of the simple test targets (FUZZ_TEST_SIMPLE) by iterating over the .kfuzztest_simple_target section, creating a corresponding debugfs directory with a write-only 'input_simple' file for each of them. Writing to an 'input_simple' file triggers the following fuzzing sequence: 1. The binary input is allocated and copied from userspace into a kernel buffer. 2. The buffer and its length are passed immediately to the user-defined test logic. 3. The kernel is tainted with TAINT_TEST to indicate that untrusted input has been fed directly to the internal kernel functions. This lightweight implementation relies on the caller (e.g., a fuzzer or script) to provide raw binary data that the target function can process. Signed-off-by: Ethan Graham --- PR v4: - Remove parsing, relocation, and KASAN poisoning logic to support the move to a simple-only design. - Remove the '_config' debugfs directory and associated state tracking (minimum alignment, invocation counts) to reduce complexity. - Enforce zero offset in `kfuzztest_write_cb_common` to ensure inputs are passed down as single, contiguous blocks. PR v3: - Handle FUZZ_TEST_SIMPLE targets by creating a write-only 'input_simple' under the fuzz target's directory. - Add implementation for `kfuzztest_write_input_cb`. PR v2: - Fix build issues identified by the kernel test robot . - Address some nits pointed out by Alexander Potapenko. PR v1: - Update kfuzztest/parse.c interfaces to take `unsigned char *` instead of `void *`, reducing the number of pointer casts. - Expose minimum region alignment via a new debugfs file. - Expose number of successful invocations via a new debugfs file. - Refactor module init function, add _config directory with entries containing KFuzzTest state information. - Account for kasan_poison_range() return value in input parsing logic. - Validate alignment of payload end. - Move static sizeof assertions into /lib/kfuzztest/main.c. - Remove the taint in kfuzztest/main.c. We instead taint the kernel as soon as a fuzz test is invoked for the first time, which is done in the primary FUZZ_TEST macro. RFC v2: - The module's init function now taints the kernel with TAINT_TEST. --- --- lib/Makefile | 2 + lib/kfuzztest/Makefile | 4 ++ lib/kfuzztest/input.c | 47 ++++++++++++++ lib/kfuzztest/main.c | 142 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 195 insertions(+) create mode 100644 lib/kfuzztest/Makefile create mode 100644 lib/kfuzztest/input.c create mode 100644 lib/kfuzztest/main.c diff --git a/lib/Makefile b/lib/Makefile index 392ff808c9b9..02789bf88499 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -325,6 +325,8 @@ obj-$(CONFIG_GENERIC_LIB_CMPDI2) +=3D cmpdi2.o obj-$(CONFIG_GENERIC_LIB_UCMPDI2) +=3D ucmpdi2.o obj-$(CONFIG_OBJAGG) +=3D objagg.o =20 +obj-$(CONFIG_KFUZZTEST) +=3D kfuzztest/ + # pldmfw library obj-$(CONFIG_PLDMFW) +=3D pldmfw/ =20 diff --git a/lib/kfuzztest/Makefile b/lib/kfuzztest/Makefile new file mode 100644 index 000000000000..3cf5da5597a4 --- /dev/null +++ b/lib/kfuzztest/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_KFUZZTEST) +=3D kfuzztest.o +kfuzztest-objs :=3D main.o input.o diff --git a/lib/kfuzztest/input.c b/lib/kfuzztest/input.c new file mode 100644 index 000000000000..aae966ea76b3 --- /dev/null +++ b/lib/kfuzztest/input.c @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * KFuzzTest input handling. + * + * Copyright 2025 Google LLC + */ +#include + +int kfuzztest_write_cb_common(struct file *filp, const char __user *buf, s= ize_t len, loff_t *off, void **test_buffer) +{ + void *buffer; + ssize_t ret; + + /* + * Enforce a zero-offset to ensure that all data is passed down in a + * single contiguous blob and not fragmented across multiple write + * system calls. + */ + if (*off) + return -EINVAL; + + /* + * Taint the kernel on the first fuzzing invocation. The debugfs + * interface provides a high-risk entry point for userspace to + * call kernel functions with untrusted input. + */ + if (!test_taint(TAINT_TEST)) + add_taint(TAINT_TEST, LOCKDEP_STILL_OK); + + if (len > KFUZZTEST_MAX_INPUT_SIZE) { + pr_warn("kfuzztest: user input of size %zu is too large", len); + return -EINVAL; + } + + buffer =3D kzalloc(len, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + ret =3D simple_write_to_buffer(buffer, len, off, buf, len); + if (ret !=3D len) { + kfree(buffer); + return -EFAULT; + } + + *test_buffer =3D buffer; + return 0; +} diff --git a/lib/kfuzztest/main.c b/lib/kfuzztest/main.c new file mode 100644 index 000000000000..40a9e56c81ad --- /dev/null +++ b/lib/kfuzztest/main.c @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KFuzzTest core module initialization and debugfs interface. + * + * Copyright 2025 Google LLC + */ +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Ethan Graham "); +MODULE_DESCRIPTION("Kernel Fuzz Testing Framework (KFuzzTest)"); + +extern const struct kfuzztest_simple_target __kfuzztest_simple_targets_sta= rt[]; +extern const struct kfuzztest_simple_target __kfuzztest_simple_targets_end= []; + +struct target_fops { + struct file_operations target_simple; +}; + +/** + * struct kfuzztest_state - global state for the KFuzzTest module + * + * @kfuzztest_dir: The root debugfs directory, /sys/kernel/debug/kfuzztest= /. + * @num_targets: number of registered targets. + * @target_fops: array of file operations for each registered target. + */ +struct kfuzztest_state { + struct dentry *kfuzztest_dir; + struct target_fops *target_fops; + size_t num_targets; +}; + +static struct kfuzztest_state state; + +static void cleanup_kfuzztest_state(struct kfuzztest_state *st) +{ + debugfs_remove_recursive(st->kfuzztest_dir); + st->num_targets =3D 0; + kfree(st->target_fops); + st->target_fops =3D NULL; +} + +static const umode_t KFUZZTEST_INPUT_PERMS =3D 0222; + +static int initialize_target_dir(struct kfuzztest_state *st, const struct = kfuzztest_simple_target *targ, + struct target_fops *fops) +{ + struct dentry *dir, *input_simple; + int err =3D 0; + + dir =3D debugfs_create_dir(targ->name, st->kfuzztest_dir); + if (!dir) + err =3D -ENOMEM; + else if (IS_ERR(dir)) + err =3D PTR_ERR(dir); + if (err) { + pr_info("kfuzztest: failed to create /kfuzztest/%s dir", targ->name); + goto out; + } + + input_simple =3D debugfs_create_file("input_simple", KFUZZTEST_INPUT_PERM= S, dir, NULL, &fops->target_simple); + if (!input_simple) + err =3D -ENOMEM; + else if (IS_ERR(input_simple)) + err =3D PTR_ERR(input_simple); + if (err) + pr_info("kfuzztest: failed to create /kfuzztest/%s/input_simple", targ->= name); +out: + return err; +} + +/** + * kfuzztest_init - initializes the debug filesystem for KFuzzTest + * + * Each registered target in the ".kfuzztest_simple_target" section gets i= ts own + * subdirectory under "/sys/kernel/debug/kfuzztest/" containing= one + * write-only "input_simple" file used for receiving binary inputs from + * userspace. + * + * @return 0 on success or an error + */ +static int __init kfuzztest_init(void) +{ + const struct kfuzztest_simple_target *targ; + int err =3D 0; + int i =3D 0; + + state.num_targets =3D __kfuzztest_simple_targets_end - __kfuzztest_simple= _targets_start; + state.target_fops =3D kzalloc(sizeof(struct target_fops) * state.num_targ= ets, GFP_KERNEL); + if (!state.target_fops) + return -ENOMEM; + + /* Create the main "kfuzztest" directory in /sys/kernel/debug. */ + state.kfuzztest_dir =3D debugfs_create_dir("kfuzztest", NULL); + if (!state.kfuzztest_dir) { + pr_warn("kfuzztest: could not create 'kfuzztest' debugfs directory"); + return -ENOMEM; + } + if (IS_ERR(state.kfuzztest_dir)) { + pr_warn("kfuzztest: could not create 'kfuzztest' debugfs directory"); + err =3D PTR_ERR(state.kfuzztest_dir); + state.kfuzztest_dir =3D NULL; + return err; + } + + for (targ =3D __kfuzztest_simple_targets_start; targ < __kfuzztest_simple= _targets_end; targ++, i++) { + state.target_fops[i].target_simple =3D (struct file_operations){ + .owner =3D THIS_MODULE, + .write =3D targ->write_input_cb, + }; + err =3D initialize_target_dir(&state, targ, &state.target_fops[i]); + /* + * Bail out if a single target fails to initialize. This avoids + * partial setup, and a failure here likely indicates an issue + * with debugfs. + */ + if (err) + goto cleanup_failure; + pr_info("kfuzztest: registered target %s", targ->name); + } + return 0; + +cleanup_failure: + cleanup_kfuzztest_state(&state); + return err; +} + +static void __exit kfuzztest_exit(void) +{ + pr_info("kfuzztest: exiting"); + cleanup_kfuzztest_state(&state); +} + +module_init(kfuzztest_init); +module_exit(kfuzztest_exit); --=20 2.51.0 From nobody Sat Feb 7 08:22:57 2026 Received: from mail-ej1-f65.google.com (mail-ej1-f65.google.com [209.85.218.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 57561321F27 for ; Mon, 12 Jan 2026 19:28:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.65 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768246129; cv=none; b=EkojE9Oc5HCF1KazHdpQp/7PHF9opej+AM4l6SFUQCgdRFo10mZ+E+1joU+riazG4ZP50cp/rR7ki8UlWku1NKsuFZwpx4JniXqY/8wfkX7+mUlkSACEzuOZ6jK2L7qK2S3qLw1gr3JV9ewOPrtN/EqueEqcOj/67gCc/x/W/rU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768246129; c=relaxed/simple; bh=jFLv86BSbm6LGv1/W2jurRZOHf2tOTo1lOReNMLMGX8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=J8eNhjOimJe3HfNoMGK/oi+T6GzlHjnell4iq4FcBxeGVrSugfoubD+bBktRVnavWKm/7RVJd00kHpfK+3dr5QmdFrAsswFICfXQoxIjlyHc9IWNQdkQrmW4nDGkvmTQYXX1EQfLAQF6zcHYaXoWsSRcRmG16nF8uDvjdP6J0FY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=YBZrAN42; arc=none smtp.client-ip=209.85.218.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="YBZrAN42" Received: by mail-ej1-f65.google.com with SMTP id a640c23a62f3a-b871ba73f49so190263466b.1 for ; Mon, 12 Jan 2026 11:28:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768246125; x=1768850925; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=CTAiuUIttCbMVHuYgOxGCwhf3npydnD/rY6k0kTCwMc=; b=YBZrAN42i2+QICBwQn8zRbzUK9JPjZU1Je3e1mgy5QGj663VcNe2zcl9EBp7PK2t6p 21lD7NJKlgrqZtVPRVgEvvHuQV4gmlNWlP6aFhv/FQ93hE991W9/zIEf3mGbJ6eVqSuO Y6kAC4GDf/NoeX2PimiPfl37vaDXZbSI86uM0CfNse7Cczy4C5IH6Iwi9IkyIFsw2srv 6zK7MDdzoRwzZ1N8eKYirLFHaxr5Emgfo1y+Z9MUPbXeAr4IkxDUOJ92DB5s6LcDQ/Rw isgcj9BP4SaqrPgkFLsHzjZbDm0SWzbwAckYGQWc0C9NHg3LhilhtBzKdhwFU60M6GbW Dyeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768246125; x=1768850925; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=CTAiuUIttCbMVHuYgOxGCwhf3npydnD/rY6k0kTCwMc=; b=mBzkct2//I7ErM88O+OwCqvWqY7i2OvQGB/UFBM9t6x7Tckszw9Y3hFCHMfwXvHL4E 1E+OAzaiJJJECdxrOPTWczS+yhLiV7elrLmL0Ggv+86ACpX8pbYniTpmO2yvJXMXDOd1 zusgJgbd19H8QbQsin3wWpaoHCC14b3vWEXtX6GOS+jdMBjYwifUoIZ9AvNTklGmG2mt fC+h5rWs7xvJxaik0dhMSzngtgO+nPm8crTqkRdFo/6ZT588SuUFYbAPiM61iEu97CZN QeNXjoR7CUTO9byclen0Chq3yQO9YjZ/c8UjQo8bxMHyRiLjzo8+8Gzknps4oGxFspPk /L1A== X-Forwarded-Encrypted: i=1; AJvYcCVkxaT/C+f9wz1y79uPs3B01/QFuU8Q04w22OM9jyfveOMD2j1xS5pFLBSenVFKHtHWGRsquSNHxDAu2Tk=@vger.kernel.org X-Gm-Message-State: AOJu0YwtuI82kYDHz4VVMzq8w7LjoErYqPsmj4fF2nRJP+yd4e/elwiS 6I0dR4Q0KqVm3xCQriFUoP5WAXEm2Pfcu3wNm6l5jtjyNun4krqSKhH8 X-Gm-Gg: AY/fxX4EzWfEMCjd1Q6X6ybpklpUvl73kGhJj/OOfiUeJSTF3MUgCYe+2hY1X42DZti PQTtu3WWt7kiIag7QBr83Qiru2aSbgZPnpLIWf4Ax8z2DEdpK2U82nPLwXJ07nPQCqVEuTiCVW/ 0ee0NRGZWK3savSUkvRfzRd8wGpUt5cgM75gzZfSwsMWmUQhDrZ/l6mpgxxmWcohkQch8s2bu3D ulFM35y248uMNVHGZH7ryBiTNoBKy4D+M1b5ZGTwyodQuLdnCV7LB72xPjmc6YpY9fkyEnJxvt3 LPJlcC41iBpUVZR/fm5kfqUI+5cGPxUB0nAND42c1pSHu8P0+6y/EDyUXiJmkdaqqSA4pxWJazO +h0+F+nSmHJFxSHX9ilX1RjWmejkncLAQhwhAuxQ2TS5nPA9QwNVC7r2iLUMkk8YWu7mYGMp637 PRp8b0HZ3KWSaNItr4bianJ+0APXWBbevtkoQcQsAIBPZfi7242Q== X-Google-Smtp-Source: AGHT+IFg3EfHyzwE3s5+1CIr8vfZlNWItuYnwllGRGRLiahyarhLhMPRBnC81D17BfEIAlYLna4bQw== X-Received: by 2002:a17:906:c141:b0:b87:1c74:a8c6 with SMTP id a640c23a62f3a-b871c74ab49mr405692366b.57.1768246124624; Mon, 12 Jan 2026 11:28:44 -0800 (PST) Received: from ethan-tp (xdsl-31-164-106-179.adslplus.ch. [31.164.106.179]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6507bf667fcsm18108959a12.29.2026.01.12.11.28.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Jan 2026 11:28:44 -0800 (PST) From: Ethan Graham To: ethan.w.s.graham@gmail.com, glider@google.com Cc: akpm@linux-foundation.org, 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, ebiggers@kernel.org, elver@google.com, gregkh@linuxfoundation.org, 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, mcgrof@kernel.org, rmoar@google.com, shuah@kernel.org, sj@kernel.org, skhan@linuxfoundation.org, tarasmadan@google.com, wentaoz5@illinois.edu Subject: [PATCH v4 3/6] kfuzztest: add ReST documentation Date: Mon, 12 Jan 2026 20:28:24 +0100 Message-ID: <20260112192827.25989-4-ethan.w.s.graham@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260112192827.25989-1-ethan.w.s.graham@gmail.com> References: <20260112192827.25989-1-ethan.w.s.graham@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add Documentation/dev-tools/kfuzztest.rst and reference it in the dev-tools index. Signed-off-by: Ethan Graham --- PR v4: - Rework documentation to focus exclusively on the `FUZZ_TEST_SIMPLE` macro, removing all references to the legacy complex targets and serialization format. - Remove obsolete sections describing DWARF constraints, annotations, and the userspace bridge tool. - Add examples demonstrating basic usage with standard command-line tools. --- --- Documentation/dev-tools/index.rst | 1 + Documentation/dev-tools/kfuzztest.rst | 152 ++++++++++++++++++++++++++ include/linux/kfuzztest.h | 2 + 3 files changed, 155 insertions(+) create mode 100644 Documentation/dev-tools/kfuzztest.rst diff --git a/Documentation/dev-tools/index.rst b/Documentation/dev-tools/in= dex.rst index 65c54b27a60b..00ccc4da003b 100644 --- a/Documentation/dev-tools/index.rst +++ b/Documentation/dev-tools/index.rst @@ -32,6 +32,7 @@ Documentation/process/debugging/index.rst kfence kselftest kunit/index + kfuzztest ktap checkuapi gpio-sloppy-logic-analyzer diff --git a/Documentation/dev-tools/kfuzztest.rst b/Documentation/dev-tool= s/kfuzztest.rst new file mode 100644 index 000000000000..f5ccf545d45d --- /dev/null +++ b/Documentation/dev-tools/kfuzztest.rst @@ -0,0 +1,152 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. Copyright 2025 Google LLC + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Kernel Fuzz Testing Framework (KFuzzTest) +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Overview +=3D=3D=3D=3D=3D=3D=3D=3D + +The Kernel Fuzz Testing Framework (KFuzzTest) is a framework designed to e= xpose +internal kernel functions to a userspace fuzzing engine. + +It is intended for testing stateless or low-state functions that are diffi= cult +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 sep= arate +userspace library or that its dependencies be stubbed out. + +The framework consists of two main components: + +1. An API, based on the ``FUZZ_TEST_SIMPLE`` macro, for defining test tar= gets + directly in the kernel tree. +2. A ``debugfs`` interface through which a userspace fuzzer submits raw + binary test inputs. + +.. warning:: + KFuzzTest is a debugging and testing tool. It exposes internal kernel + functions to userspace with minimal sanitization and is designed for + use in controlled test environments only. It must **NEVER** be enabled + in production kernels. + +Supported Architectures +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +KFuzzTest is designed for generic architecture support. It has only been +explicitly tested on x86_64. + +Usage +=3D=3D=3D=3D=3D + +To enable KFuzzTest, configure the kernel with:: + + CONFIG_KFUZZTEST=3Dy + +which depends on ``CONFIG_DEBUGFS`` for receiving userspace inputs, and +``CONFIG_DEBUG_KERNEL`` as an additional guardrail for preventing KFuzzTest +from finding its way into a production build accidentally. + +The KFuzzTest sample fuzz targets can be built in with +``CONFIG_SAMPLE_KFUZZTEST``. + +KFuzzTest currently only supports targets that are built into the kernel, = as the +core module's startup process discovers fuzz targets from a dedicated ELF +section during startup. + +Defining a KFuzzTest target +--------------------------- + +A fuzz target should be defined in a .c file. The recommended place to def= ine +this is under the subsystem's ``/tests`` directory in a ``_kfuz= z.c`` +file, following the convention used by KUnit. The only strict requirement = is +that the function being fuzzed is visible to the fuzz target. + +Use the ``FUZZ_TEST_SIMPLE`` macro to define a fuzz target. This macro is +designed for functions that accept a buffer and its length (e.g., +``(const char *data, size_t datalen)``). + +This macro provides ``data`` and ``datalen`` variables implicitly to the t= est +body. + +.. code-block:: c + + /* 1. The kernel function that we want to fuzz. */ + int process_data(const char *data, size_t len); + + /* 2. Define the fuzz target with the FUZZ_TEST_SIMPLE macro. */ + FUZZ_TEST_SIMPLE(test_process_data) + { + /* 3. Call the kernel function with the provided input. */ + process_data(data, datalen); + } + +A ``FUZZ_TEST_SIMPLE`` target creates a debugfs directory +(``/sys/kernel/debug/kfuzztest/``) containing a single write-on= ly +file ``input_simple``: writing a raw blob to this file will invoke the fuzz +target, passing the blob as ``(data, datalen)``. + +Basic Usage +^^^^^^^^^^^ + +Because the interface accepts raw binary data, targets can be smoke-tested= or +fuzzed naively using standard command-line tools without any external +dependencies. + +For example, to feed 128 bytes of random data to the target defined above: + +.. code-block:: sh + + head -c 128 /dev/urandom > \ + /sys/kernel/debug/kfuzztest/test_process_data/input_simple + +Integration with Fuzzers +^^^^^^^^^^^^^^^^^^^^^^^^ + +The simple interface makes it easy to integrate with userspace fuzzers (e.= g., +LibFuzzer, AFL++, honggfuzz). A LibFuzzer, for example, harness may look l= ike +so: + +.. code-block:: c + + /* Path to the simple target's input file */ + const char *filepath =3D "/sys/kernel/debug/kfuzztest/test_process_dat= a/input_simple"; + + extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size= ) { + FILE *f =3D fopen(filepath, "w"); + if (!f) { + return 0; /* Fuzzer should not stop. */ + } + /* Write the raw fuzzer input directly. */ + fwrite(Data, 1, Size, f); + fclose(f); + return 0; + } + +Note that while it is simple to feed inputs to KFuzzTest targets, kernel +coverage collection is key for the effectiveness of a coverage-guided fuzz= er; +setup of KCOV or other coverage mechanisms is outside of KFuzzTest's scope. + +Metadata +-------- + +The ``FUZZ_TEST_SIMPLE`` macro embeds metadata into a dedicated section wi= thin +the main ``.data`` section of the final ``vmlinux`` binary: +``.kfuzztest_simple_target``, delimited by ``__kfuzztest_simple_targets_st= art`` +and ``__kfuzztest_simple_targets_end``. + +The metadata serves two purposes: + +1. The core module uses the ``.kfuzztest_simple_target`` section at boot to + discover every test instance and create its ``debugfs`` directory and + ``input_simple`` file. +2. Tooling can use this section for offline discovery. While available fuzz + targets can be trivially enumerated at runtime by listing the directori= es + under ``/sys/kernel/debug/kfuzztest``, the metadata allows fuzzing + orchestrators to index available fuzz targets directly from the ``vmlin= ux`` + binary without needing to boot the kernel. + +This metadata consists of an array of ``struct kfuzztest_simple_target``. = The +``name`` field within this struct references data in other locations of the +``vmlinux`` binary, and therefore a userspace tool that parses the ELF must +resolve these pointers to read the underlying data. diff --git a/include/linux/kfuzztest.h b/include/linux/kfuzztest.h index 62fce9267761..4f210c5ec919 100644 --- a/include/linux/kfuzztest.h +++ b/include/linux/kfuzztest.h @@ -3,6 +3,8 @@ * The Kernel Fuzz Testing Framework (KFuzzTest) API for defining fuzz tar= gets * for internal kernel functions. * + * For more information please see Documentation/dev-tools/kfuzztest.rst. + * * Copyright 2025 Google LLC */ #ifndef KFUZZTEST_H --=20 2.51.0 From nobody Sat Feb 7 08:22:57 2026 Received: from mail-ej1-f52.google.com (mail-ej1-f52.google.com [209.85.218.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 825B631B131 for ; Mon, 12 Jan 2026 19:28:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768246130; cv=none; b=ltfQhY9uQ+xvSMhJZ9js/hOPPZTToUcoJmMl2B7ssFb37kz3NNGIr63on6t5W+VHHQ8Mnkd+3mtj0quLv+WBHP9Vw3ufGwQS2vbVDstYB4v3GOJw9EnfOIV9gXjlieralQgasxVFDwr/X5j9a7RcpJQiXx2NvQIMoG9I+AyZfjU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768246130; c=relaxed/simple; bh=wMDRutPxox6hkPyPznb4TybXdAVmmts7fn8xxj+1g5E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nGlNIGniXsWCzSrf5lPXQS/1fHoZiY1Cr/sYFO4RUyzd40sbiJ92vfUaHK5iS2/2lY4OBil1Hy/fNlHNGb5ir2zzCv/XTshVFFnypz/xG8rInnHxM3815ZI1rK63IYCN794R4wY2sExkeuS8ldXFSKtp39yzzrUolCAs0c96ouE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=A72aTiFZ; arc=none smtp.client-ip=209.85.218.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="A72aTiFZ" Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-b8715a4d9fdso186075666b.0 for ; Mon, 12 Jan 2026 11:28:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768246127; x=1768850927; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lYn/cfzIUiLg8O0jmeN0oIUjcH6e7FhIiA9EkVEqfyc=; b=A72aTiFZspKlLlgZYax1P8HDpOEO2xHOiGMYgnPRbYrNSHj3vKsdHpmtr3xm5D3JSL 9H9K4tKuGImpsJro5mPs68y1uNQYdVpAK5G/3F2Yp9QyIEZxt9OQl6YraVyAqCgf95Wu mIzAdj6At6bh8mWmHsCIzINhu7lo6ml7WHbA8RF1JGPgfVXF499NTk/SQh8Vpsm4Qztq IXqmLza+Tr9wIr7w9WGy9+6NHdvMm7CrJA/di54Eo3ZqKpBI9XBbSf1YuOYXr0pNrd/c BVlXw4bCMp48l61QVRNLlDNhtVfn68lI9vrHawc13zCWeIB6hiIKbFT2XDXBzmzcSKM1 YV8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768246127; x=1768850927; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=lYn/cfzIUiLg8O0jmeN0oIUjcH6e7FhIiA9EkVEqfyc=; b=irkMnFHgmpNpR6U6SOdHgbP51KYzN8frt2TQkl7mOOiJeC/lC4banOA4Xkp08LF7on N7NfFD1WnuvX83UhkupijyANIuPXeW1OSvxz9vzOeT//AkC0DFgzmmqFn/2naUHJKAs0 g2UVqEfWvGVvgEix7EykG849RR4R3i0sKKj7imvb9bYjs+im8OWsPbvKqWA3WFjf7A/b AQ3BnmbxHfx9Fio+TJG64xXo9/0MOT3voJyd92susqcVjLK1Duf0yq2YF5ucgX43ar9c CkcLTGdy4f20xtkYPiH9DhRwYApVKTgebTAXHICJh+0u0HaZyKkDLkwYFT0Oov4nar4U Hshg== X-Forwarded-Encrypted: i=1; AJvYcCXCZ6q79ZnxA78iiSWLmNfsOP46bmrgNvnqn+fKhvzpSIkr0RWus4BQiZrdqpdMw+3RpTElKWzzjwoRjsg=@vger.kernel.org X-Gm-Message-State: AOJu0Ywb5lBfbg7tiRiWC5vdxNQIqpK6QiFjZVQefq5olPSldByGjbzd 3e3jWqEB9lzzJXMxmo9Pr1crNo7ZpJjLJ4XDVA/s6P/Pd9CiYWAFoy32 X-Gm-Gg: AY/fxX4Jj05uEBAeMRd1rdtyec2XALj43nqXffz3yaLeTlfTymV4BPquYTWafg3xvwb fApIQz1Q8CyTLgqeDh5gxjKcjtLmG4vJ+ipb9LRMSYwXyMM6K61sDYyk1+GIDZFPGQWMxzCJ8/J gPheHRYyXIhXbrk0vtjBq0uJF4SqPswJQmSx5ZKeQwOffhHk0JQRftLVgLlMo+yQ6UAkvFEolZL UX9xTXogFqPUWndHOmsWxPYJFJWhalt5Zh47KYZCuDz2p5z8UCFTP6oIr7AD+3IsjZcc9TkD6vO EolCGesH0NtZwrazUd0/ZJV+GHwUscmFjbUVuiZmqdBdCiwlK0Wx5DjpP901VfifNj3gU6dr170 9YOrjZPyRQ+QKixRK6zIqkZlGlg2vtI16/EG6QZTKxKL01DtXSSrCAXEW5qMg7Jrl+SZPkTbI7M fAZs8viscEz1wvRjPFsBtLaByexCl2SLoV77xKpfb9i4XWgp53Bw== X-Google-Smtp-Source: AGHT+IF4pPwfnNX2FK6K6VgQD0pVFZdgZJNgLaaNTxNX+cYNIN/F+0YErplY46SPSS0fwiEVEMONCQ== X-Received: by 2002:a17:906:9f87:b0:b73:2b08:ac70 with SMTP id a640c23a62f3a-b844539fc4fmr1937923066b.49.1768246126219; Mon, 12 Jan 2026 11:28:46 -0800 (PST) Received: from ethan-tp (xdsl-31-164-106-179.adslplus.ch. [31.164.106.179]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6507bf667fcsm18108959a12.29.2026.01.12.11.28.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Jan 2026 11:28:45 -0800 (PST) From: Ethan Graham To: ethan.w.s.graham@gmail.com, glider@google.com Cc: akpm@linux-foundation.org, 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, ebiggers@kernel.org, elver@google.com, gregkh@linuxfoundation.org, 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, mcgrof@kernel.org, rmoar@google.com, shuah@kernel.org, sj@kernel.org, skhan@linuxfoundation.org, tarasmadan@google.com, wentaoz5@illinois.edu Subject: [PATCH v4 4/6] kfuzztest: add KFuzzTest sample fuzz targets Date: Mon, 12 Jan 2026 20:28:25 +0100 Message-ID: <20260112192827.25989-5-ethan.w.s.graham@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260112192827.25989-1-ethan.w.s.graham@gmail.com> References: <20260112192827.25989-1-ethan.w.s.graham@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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_SIMPLE() macro. It also serves as a runtime sanity check, ensuring that the framework correctly passes the input buffer and that KASAN correctly detects out-of-bounds memory accesses (in this case, a buffer underflow) on the allocated test data. This target can be fuzzed naively by writing random data into the debugfs 'input_simple' file and verifying that the KASAN report is triggered. Signed-off-by: Ethan Graham Acked-by: Alexander Potapenko --- PR v4: - Remove the `test_underflow_on_nested_buffer` sample target which relied on the now removed `FUZZ_TEST` macro. - Update the sample comment to demonstrate naive fuzzing (using `head`) instead of the removed bridge tool. - Fix stale comments referencing internal layout structures. PR v3: - Use the FUZZ_TEST_SIMPLE macro in the `underflow_on_buffer` sample fuzz target instead of FUZZ_TEST. PR v2: - Fix build issues pointed out by the kernel test robot . --- --- samples/Kconfig | 7 ++++ samples/Makefile | 1 + samples/kfuzztest/Makefile | 3 ++ samples/kfuzztest/underflow_on_buffer.c | 52 +++++++++++++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 samples/kfuzztest/Makefile create mode 100644 samples/kfuzztest/underflow_on_buffer.c diff --git a/samples/Kconfig b/samples/Kconfig index 6e072a5f1ed8..303a9831d404 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). =20 +config SAMPLE_KFUZZTEST + bool "Build KFuzzTest sample targets" + depends on KFUZZTEST + help + Build KFuzzTest sample targets that serve as selftests for raw input + delivery and KASAN out-of-bounds detection. + source "samples/rust/Kconfig" =20 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) +=3D damon/ obj-$(CONFIG_SAMPLE_DAMON_PRCL) +=3D damon/ obj-$(CONFIG_SAMPLE_DAMON_MTIER) +=3D damon/ obj-$(CONFIG_SAMPLE_HUNG_TASK) +=3D hung_task/ +obj-$(CONFIG_SAMPLE_KFUZZTEST) +=3D kfuzztest/ obj-$(CONFIG_SAMPLE_TSM_MR) +=3D tsm-mr/ diff --git a/samples/kfuzztest/Makefile b/samples/kfuzztest/Makefile new file mode 100644 index 000000000000..2dc5d424824d --- /dev/null +++ b/samples/kfuzztest/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_SAMPLE_KFUZZTEST) +=3D underflow_on_buffer.o diff --git a/samples/kfuzztest/underflow_on_buffer.c b/samples/kfuzztest/un= derflow_on_buffer.c new file mode 100644 index 000000000000..5568c5e6be7a --- /dev/null +++ b/samples/kfuzztest/underflow_on_buffer.c @@ -0,0 +1,52 @@ +// 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 + */ + +/** + * test_underflow_on_buffer - a sample fuzz target + * + * This sample fuzz target serves to illustrate the usage of the + * FUZZ_TEST_SIMPLE macro, as well as provide a sort of self-test that KFu= zzTest + * functions correctly for trivial fuzz targets. In KASAN builds, fuzzing = this + * harness should trigger a report for every input (provided that its leng= th is + * greater than 0 and less than KFUZZTEST_MAX_INPUT_SIZE). + * + * This harness can be invoked (naively) like so: + * head -c 128 /dev/urandom > \ + * /sys/kernel/debug/kfuzztest/test_underflow_on_buffer/input_simple + */ +#include + +static void underflow_on_buffer(char *buf, size_t buflen) +{ + size_t i; + + /* + * Print the address range of `buf` to allow correlation with the + * subsequent KASAN report. + */ + pr_info("buf =3D [%px, %px)", buf, buf + buflen); + + /* First ensure that all bytes in `buf` are accessible. */ + for (i =3D 0; i < buflen; i++) + READ_ONCE(buf[i]); + /* + * Provoke a buffer underflow on the first byte preceding `buf`, + * triggering a KASAN report. + */ + READ_ONCE(*((char *)buf - 1)); +} + +/** + * Define the fuzz target. This wrapper ensures that the `underflow_on_buf= fer` + * function is invoked with the data provided from userspace. + */ +FUZZ_TEST_SIMPLE(test_underflow_on_buffer) +{ + underflow_on_buffer(data, datalen); + return 0; +} --=20 2.51.0 From nobody Sat Feb 7 08:22:57 2026 Received: from mail-ed1-f49.google.com (mail-ed1-f49.google.com [209.85.208.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BF3E43242D7 for ; Mon, 12 Jan 2026 19:28:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768246132; cv=none; b=Hs7/NpcZrNHcMpCWTMGZ12ItLwKSt0cp+2xGZ69wFEYBIY6VK6Jv1oRECnNfz23XCMUk+u4pyzG4U5Mx/EDxSkfYNFWIMcMJLCq+KxdJ183OELGm2TWaTMSHRB1rpHS/2ZuF6UGwazVjuYKhENXvY8OGz3ttQfrwmlRO5uqV3oY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768246132; c=relaxed/simple; bh=T1ghGRckBD0Pyg/AIxM0N0GOULp6cwu0eueedEPTUkw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QTds2Q4BsYQFTvVY7JXBGg7D3P9vNISaAInlUjssLqw3u+xEwzzLTUc1b2qFcI2ydhnWQiw7ZhVrhkctVlIvBybBX05JonXu+RPMB7N5EWET98zRRSkPyhishWbHTvpbGVB9GJ6ddIq3kEPLJwfuXvPuGXQuw3NTVcxeQIdECW4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=fj8J4z5o; arc=none smtp.client-ip=209.85.208.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fj8J4z5o" Received: by mail-ed1-f49.google.com with SMTP id 4fb4d7f45d1cf-64d0d41404cso11108539a12.0 for ; Mon, 12 Jan 2026 11:28:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768246128; x=1768850928; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=scWvVJzBtZkgblH2r+AxXX3I8YFcDE4LdHFKMGvKaXc=; b=fj8J4z5oMjhXk/TAPFLWoo1NqXSuMRslawhcGPlP/Qm33aBSaaumSOqBKzgCvTcrPF HOiRFO4cfhChzmf8byRP8PzPZK4/5AQEI3Zlug/riHXx4TeGyFrDDreD9NMQC8sp7hXi dSYbvic5rj6uzg6OZiPdX2R6Jk8dceoCooolWhHR8TmAKjZxvEcnrMYJWE3S7vJl2Tog nLl9Hz1kBKZ6bo7KcrqmsQwJ7QdqZHyRNMY7suTqA0TbhTm2QldWa+QzEw6xEhclddwp UUVycIOUCkLNqCxMWfW3E+Kx8pr6wAJ9O6zIhByjldBn1ep7Gcagi+Ogp7o55HEEmvbN 9UVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768246128; x=1768850928; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=scWvVJzBtZkgblH2r+AxXX3I8YFcDE4LdHFKMGvKaXc=; b=Tz6up53CnOYLy0nRMpAbymV48XDek4ZYcr6LlOsNHO4oOkFkE3WNnrWLLtD8U1fLQ2 KzbBCeFDgdmENvXV2lzRRct4SeKXl90XEZbu/loyNhBO6wgLDsTk9jzaME7kZsw7dyNS PIDPtvSVFrzCk+GZsycrqf/vovGvKnwasnzkDCuiKcUK82y4Ga1+6T/hJw1jaa7LjZiD NMtY1QuNsX2udvA6m3ejNQI7VenImQh4BSQq//XEuGpsBcGtBh9Nu+0cE3KkEFyliz39 vtL0Ms9kqQ1pvYu9HDtlEXwp4bcl1zcF7RAozby2EqCYUzLZWZlIXfd+E3yKODNiZOnz dN2g== X-Forwarded-Encrypted: i=1; AJvYcCVuqhr8AIn9xE4TcHg65jOkQkEMC2Yk6E2ASgyC7J0q7Z87HhhXoVkn9R3aszPaSxCRxSqYgT+4q9/Dtfg=@vger.kernel.org X-Gm-Message-State: AOJu0YxhXleQTkPiiIOsoNU+dswuy4lvjKt1iRbyNoQu2VvkBNgSsb6C JBvVuk3A22kiOshYY+2/OQE6f8eZhD0/J++XwSB7f1KDCqgBor708gav X-Gm-Gg: AY/fxX4qNxMkV4Bdesk1v4lNEwSCnSsaw+Kwm0lf+rAA7rmG7swOJx2yZk153gPJKjB XuCuBCl9o6yLyLdaeXb6X91qgo3Xq1e/9nwyZWQ14ZyDRK/6jGv+KljzNJSEuFmUeq2r3DibxSt XUNe/zj+GAkrCR/bbmarLF7N+OMxaV3ZjW1Des8+Zc8xzkSIWuYNNUCwVtY8m3+8TxhbahWx0Xk BJYlHknoEWXzT7GhrRfI4DHFpt1fOlU2hWoSpU7YCIP9LtUneSouAQP65Nxa39blyzqOZZFvwkU mCs+usWStVIaT5eszbghGvGWrOixPWUaXdJ+/jc9GlAu+Ewpncs/kVEDlRjzeoo5y5eMQn3XT3x eidXHjr8QDUyK2D4sS3IxPjXPvYHQOS6JV5zubNN5w5ppL0+qDUlC8g0uWNtTrP4thna59JfGKP RkodV8s2F/7fDO2kODv5Z39VghOe+LJDUhZF1SFmPAk9eHCpVIoQ== X-Google-Smtp-Source: AGHT+IGPfeGvnJT5nmBAHSLDQSoFK40ixCTsrNs53O6zDl7hozUe2ok/2s0XG0MJ5qFaw2WUbDeLwg== X-Received: by 2002:a05:6402:1e8c:b0:64d:f49:52aa with SMTP id 4fb4d7f45d1cf-65097dc6439mr18130109a12.3.1768246127869; Mon, 12 Jan 2026 11:28:47 -0800 (PST) Received: from ethan-tp (xdsl-31-164-106-179.adslplus.ch. [31.164.106.179]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6507bf667fcsm18108959a12.29.2026.01.12.11.28.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Jan 2026 11:28:47 -0800 (PST) From: Ethan Graham To: ethan.w.s.graham@gmail.com, glider@google.com Cc: akpm@linux-foundation.org, 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, ebiggers@kernel.org, elver@google.com, gregkh@linuxfoundation.org, 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, mcgrof@kernel.org, rmoar@google.com, shuah@kernel.org, sj@kernel.org, skhan@linuxfoundation.org, tarasmadan@google.com, wentaoz5@illinois.edu Subject: [PATCH v4 5/6] crypto: implement KFuzzTest targets for PKCS7 and RSA parsing Date: Mon, 12 Jan 2026 20:28:26 +0100 Message-ID: <20260112192827.25989-6-ethan.w.s.graham@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260112192827.25989-1-ethan.w.s.graham@gmail.com> References: <20260112192827.25989-1-ethan.w.s.graham@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add KFuzzTest targets for pkcs7_parse_message, rsa_parse_pub_key, and rsa_parse_priv_key to serve as real-world examples of how the framework is used. These functions are ideal candidates for KFuzzTest as they perform complex parsing of user-controlled data but are not directly exposed at the syscall boundary. This makes them difficult to exercise with traditional fuzzing tools and showcases the primary strength of the KFuzzTest framework: providing an interface to fuzz internal functions. To validate the effectiveness of the framework on these new targets, we injected two artificial bugs and let syzkaller fuzz the targets in an attempt to catch them. The first of these was calling the asn1 decoder with an incorrect input from pkcs7_parse_message, like so: - ret =3D asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen); + ret =3D asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen + 1); The second was bug deeper inside of asn1_ber_decoder itself, like so: - for (len =3D 0; n > 0; n--) + for (len =3D 0; n >=3D 0; n--) syzkaller was able to trigger these bugs, and the associated KASAN slab-out-of-bounds reports, within seconds. The targets are defined within crypto/asymmetric-keys/tests. Signed-off-by: Ethan Graham --- PR v4: - Use pkcs7_free_message() instead of kfree() on the success path of the pkcs7_parse_message fuzz target. - Dropped Ignat Korchagin's reviewed-by due to the functional change in switching from kfree to pkcs7_free_message. - Restrict introduced fuzz targets to build only when their dependencies (CONFIG_PKCS7_MESSAGE_PARSER and CONFIG_CRYPTO_RSA) are built-in. This prevents linker errors when they are configured as modules, as KFuzzTest symbols are not exported. PR v3: - Use the FUZZ_TEST_SIMPLE macro for all introduced fuzz targets as they each take `(data, datalen)` pairs. This also removes the need for explicit constraints and annotations which become implicit. PR v2: - Make fuzz targets also depend on the KConfig options needed for the functions they are fuzzing, CONFIG_PKCS7_MESSAGE_PARSER and CONFIG_CRYPTO_RSA respectively. - Fix build issues pointed out by the kernel test robot . - Account for return value of pkcs7_parse_message, and free resources if the function call succeeds. PR v1: - Change the fuzz target build to depend on CONFIG_KFUZZTEST=3Dy, eliminating the need for a separate config option for each individual file as suggested by Ignat Korchagin. - Remove KFUZZTEST_EXPECT_LE on the length of the `key` field inside of the fuzz targets. A maximum length is now set inside of the core input parsing logic. RFC v2: - Move KFuzzTest targets outside of the source files into dedicated _kfuzz.c files under /crypto/asymmetric_keys/tests/ as suggested by Ignat Korchagin and Eric Biggers. --- --- crypto/asymmetric_keys/Makefile | 2 ++ crypto/asymmetric_keys/tests/Makefile | 4 ++++ crypto/asymmetric_keys/tests/pkcs7_kfuzz.c | 18 ++++++++++++++ .../asymmetric_keys/tests/rsa_helper_kfuzz.c | 24 +++++++++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 crypto/asymmetric_keys/tests/Makefile create mode 100644 crypto/asymmetric_keys/tests/pkcs7_kfuzz.c create mode 100644 crypto/asymmetric_keys/tests/rsa_helper_kfuzz.c diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makef= ile index bc65d3b98dcb..77b825aee6b2 100644 --- a/crypto/asymmetric_keys/Makefile +++ b/crypto/asymmetric_keys/Makefile @@ -67,6 +67,8 @@ obj-$(CONFIG_PKCS7_TEST_KEY) +=3D pkcs7_test_key.o pkcs7_test_key-y :=3D \ pkcs7_key_type.o =20 +obj-y +=3D tests/ + # # Signed PE binary-wrapped key handling # diff --git a/crypto/asymmetric_keys/tests/Makefile b/crypto/asymmetric_keys= /tests/Makefile new file mode 100644 index 000000000000..b43aa769e2ce --- /dev/null +++ b/crypto/asymmetric_keys/tests/Makefile @@ -0,0 +1,4 @@ +pkcs7-kfuzz-y :=3D $(and $(CONFIG_KFUZZTEST),$(filter y, $(CONFIG_PKCS7_ME= SSAGE_PARSER))) +rsa-helper-kfuzz-y :=3D $(and $(CONFIG_KFUZZTEST),$(filter y, $(CONFIG_CRY= PTO_RSA))) +obj-$(pkcs7-kfuzz-y) +=3D pkcs7_kfuzz.o +obj-$(rsa-helper-kfuzz-y) +=3D rsa_helper_kfuzz.o diff --git a/crypto/asymmetric_keys/tests/pkcs7_kfuzz.c b/crypto/asymmetric= _keys/tests/pkcs7_kfuzz.c new file mode 100644 index 000000000000..2e1a59fb6035 --- /dev/null +++ b/crypto/asymmetric_keys/tests/pkcs7_kfuzz.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * PKCS#7 parser KFuzzTest target. + * + * Copyright 2025 Google LLC + */ +#include +#include + +FUZZ_TEST_SIMPLE(test_pkcs7_parse_message) +{ + struct pkcs7_message *msg; + + msg =3D pkcs7_parse_message(data, datalen); + if (msg && !IS_ERR(msg)) + pkcs7_free_message(msg); + return 0; +} diff --git a/crypto/asymmetric_keys/tests/rsa_helper_kfuzz.c b/crypto/asymm= etric_keys/tests/rsa_helper_kfuzz.c new file mode 100644 index 000000000000..e45e8fa53190 --- /dev/null +++ b/crypto/asymmetric_keys/tests/rsa_helper_kfuzz.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * RSA key extract helper KFuzzTest targets. + * + * Copyright 2025 Google LLC + */ +#include +#include + +FUZZ_TEST_SIMPLE(test_rsa_parse_pub_key) +{ + struct rsa_key out; + + rsa_parse_pub_key(&out, data, datalen); + return 0; +} + +FUZZ_TEST_SIMPLE(test_rsa_parse_priv_key) +{ + struct rsa_key out; + + rsa_parse_priv_key(&out, data, datalen); + return 0; +} --=20 2.51.0 From nobody Sat Feb 7 08:22:57 2026 Received: from mail-ed1-f43.google.com (mail-ed1-f43.google.com [209.85.208.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 55158320A17 for ; Mon, 12 Jan 2026 19:28:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768246132; cv=none; b=kRBjXTFSZubwnoMqg/J28IQIJha+XNy8LYIyELMg6ETR+jrNLw6icgVVXZ/yLdO8daA8sBfEa1Cipa220xrqLIwCxRNyhAbDYMRBQ9C3UhXWE3h9A3jFIMGu738cMRNn6yokqr4U9pnVsP9wrTNx3mnfz2QZ0v+IM5pvxslHuDc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768246132; c=relaxed/simple; bh=zojxNT+RZbLezTydyxAsIzYgwtxcsP67AtbFNc0SDsQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dhjyRJhef9+Sl9LpYQYOr9GwwWtAcSA5giucwOYHrAwbTKS8uaN9452C6tq05biPwBklBVbyXz97LykI5haVb7F6UAXjc09TH5DnuIVAoqLyrJy+0uPVafoTFv/T7omeXY8OqougGb36R/A/XlkW5das2Pce6NaY3/5zY564gEY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=NatTr60U; arc=none smtp.client-ip=209.85.208.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="NatTr60U" Received: by mail-ed1-f43.google.com with SMTP id 4fb4d7f45d1cf-64b83949fdaso11207026a12.2 for ; Mon, 12 Jan 2026 11:28:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768246130; x=1768850930; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=sQS0SzXkMyBsX0r/DMnRoitwZR/NjZ11xjjJpvDZxFQ=; b=NatTr60UgeiWWQyqA+wUNCsI1SuWNvWELwEFUJx6Z7zqKFoXklxTadNGlkFzFh6gw/ Gbfc1DyA2sg48wtqzd1lGNbQ4DhYgAH+IZg60u3eZQbi+VF1ZneSQHUlSCfof8fL6Z2A Pvav/EdbA3oWdmRiJuOOIJ7w06640VQ6NKzeB9Ja65jdLyPeusic5363I7XxSSTSXLK6 i8oSZ1ADG3PN+dcSOpgGBjwppxfi63Jd4h5DCTzOpWXKJsHjgMP4B8jQl7BocYk+dQur NytbqWiGXWUINkIHrddsbGnX69FAtR1Ny7tKLebPE/uJXikTgTxCcXeWL8UWOJ+acWEW S8IA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768246130; x=1768850930; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=sQS0SzXkMyBsX0r/DMnRoitwZR/NjZ11xjjJpvDZxFQ=; b=lg9sAObMGMGWK+rK7YRq/T/pFs8iVE6MDxjCO5s4T3nClweXnM2k9dywA0XbvoRE+2 NbBMnjMLF/Q7ie9EXVEXG+t0lVVF3RjPlSN8aHx9QRhEPthrbPi0pFOaU/bJ6s6pxea4 kR5VQWA3LslnpFEPn7V5aJjsjMNxT5/OGR0JcyOG690RQMcVvji5xii/+jcKDG3ii2Vv sAdsgwItUZR0vFkCB0DEemI30Yh5vNOOpxKjmqWK1mB0iraGl96OMP8AWIldCz8dBXeu M7sJjwg1mgAhr9B6Vi5sxK8GRYjUsyhMnZiW6y+VhYPaS3vzNl7WE3xd/gvohWmsD0IK vvfA== X-Forwarded-Encrypted: i=1; AJvYcCXaqscdBmTjrADCNsIqLXGqL3SR68iJE9PMXgum0qSTWhbUy6eN+f5mDyJoxMVwKPocUVlJJdQrpxSmpts=@vger.kernel.org X-Gm-Message-State: AOJu0YyqaJNyt7CZ1AueKok0y9AHmHHZP3MJMOns4KSdfFig+C7+XCBZ EZ+VLli/+yWzMO/Rc/g5a+vQuEBc1pYJvh6xnHV2BwLFn5L8coW9VS2V X-Gm-Gg: AY/fxX5oTwYPYIT7mhZn5oaLgt84NStSyo20/x7RjAuX2tZs/bQ0HqKcU9R/tNKIT6i kBTC/sV7T4ac9HsHUx5qh2ieP9MjbrSe7hj3sraOfL1dwqU5RnxBo8koHxzyZYgqx5glSnOkrSj grIV5i3xV4GdZgHNPCJcWlBnnU+GopOCVmiR26Wl44XS4O7vnHrBkjSq2oUMf0rJ0kq66JWN2nr /jQKPrlYXuy8wj6KBgM/YpzP6EBE9WGpSGk4ylY+7sVrdXFeVwoRyhWZyYV9vTCv7AdmtCG0ldB yxCZolXtGG7RzsRSwKhyWtXDi2FP19k+ZlbPaIbvoKJ5wui2hcj5xwqeW6zq7nH98ARMfvrbuNW Ox1ZnOaZ3PeeFjJuRKjLAlL/LkVazHg/SBxcksZ3c/rcDQ5gGDWqelCsJRQlzBE/1rKn4f7iIx7 SsjV5S/VhYyfSL4rLAPSySpQUXZu6Mdw6rVZXbeEK0BhV0yqZplA== X-Google-Smtp-Source: AGHT+IFk8wLMtvnspL5X08nCOFuh4w793sCkSNYw871Bcc2rMNI5daxewGVPY4N9IKJlOxERKRgH1g== X-Received: by 2002:a05:6402:280f:b0:64b:3e03:63b with SMTP id 4fb4d7f45d1cf-65097e8c00fmr14927123a12.31.1768246129525; Mon, 12 Jan 2026 11:28:49 -0800 (PST) Received: from ethan-tp (xdsl-31-164-106-179.adslplus.ch. [31.164.106.179]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6507bf667fcsm18108959a12.29.2026.01.12.11.28.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Jan 2026 11:28:49 -0800 (PST) From: Ethan Graham To: ethan.w.s.graham@gmail.com, glider@google.com Cc: akpm@linux-foundation.org, 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, ebiggers@kernel.org, elver@google.com, gregkh@linuxfoundation.org, 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, mcgrof@kernel.org, rmoar@google.com, shuah@kernel.org, sj@kernel.org, skhan@linuxfoundation.org, tarasmadan@google.com, wentaoz5@illinois.edu Subject: [PATCH v4 6/6] MAINTAINERS: add maintainer information for KFuzzTest Date: Mon, 12 Jan 2026 20:28:27 +0100 Message-ID: <20260112192827.25989-7-ethan.w.s.graham@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260112192827.25989-1-ethan.w.s.graham@gmail.com> References: <20260112192827.25989-1-ethan.w.s.graham@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add myself as maintainer and Alexander Potapenko as reviewer for KFuzzTest. Signed-off-by: Ethan Graham Acked-by: Alexander Potapenko --- PR v4: - Remove reference to the kfuzztest-bridge tool that has been removed PR v3: - Update MAINTAINERS to reflect the correct location of kfuzztest-bridge under tools/testing as pointed out by SeongJae Park. --- --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6dcfbd11efef..0119816d038d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13641,6 +13641,13 @@ F: include/linux/kfifo.h F: lib/kfifo.c F: samples/kfifo/ =20 +KFUZZTEST +M: Ethan Graham +R: Alexander Potapenko +F: include/linux/kfuzztest.h +F: lib/kfuzztest/ +F: Documentation/dev-tools/kfuzztest.rst + KGDB / KDB /debug_core M: Jason Wessel M: Daniel Thompson --=20 2.51.0