[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250916090109.91132-8-ethan.w.s.graham@gmail.com>
Date: Tue, 16 Sep 2025 09:01:06 +0000
From: Ethan Graham <ethan.w.s.graham@...il.com>
To: ethangraham@...gle.com,
glider@...gle.com
Cc: andreyknvl@...il.com,
andy@...nel.org,
brauner@...nel.org,
brendan.higgins@...ux.dev,
davem@...emloft.net,
davidgow@...gle.com,
dhowells@...hat.com,
dvyukov@...gle.com,
elver@...gle.com,
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,
rmoar@...gle.com,
shuah@...nel.org,
tarasmadan@...gle.com
Subject: [PATCH v1 07/10] crypto: implement KFuzzTest targets for PKCS7 and RSA parsing
From: Ethan Graham <ethangraham@...gle.com>
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 = asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen);
+ ret = asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen + 1);
The second was bug deeper inside of asn1_ber_decoder itself, like so:
- for (len = 0; n > 0; n--)
+ for (len = 0; n >= 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 /lib/tests, alongside existing KUnit
tests.
Signed-off-by: Ethan Graham <ethangraham@...gle.com>
---
v3:
- Change the fuzz target build to depend on CONFIG_KFUZZTEST=y,
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.
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 | 2 +
crypto/asymmetric_keys/tests/pkcs7_kfuzz.c | 22 +++++++++++
.../asymmetric_keys/tests/rsa_helper_kfuzz.c | 38 +++++++++++++++++++
4 files changed, 64 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/Makefile
index bc65d3b98dcb..77b825aee6b2 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -67,6 +67,8 @@ obj-$(CONFIG_PKCS7_TEST_KEY) += pkcs7_test_key.o
pkcs7_test_key-y := \
pkcs7_key_type.o
+obj-y += 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..4ffe0bbe9530
--- /dev/null
+++ b/crypto/asymmetric_keys/tests/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_KFUZZTEST) += pkcs7_kfuzz.o
+obj-$(CONFIG_KFUZZTEST) += 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..37e02ba517d8
--- /dev/null
+++ b/crypto/asymmetric_keys/tests/pkcs7_kfuzz.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * PKCS#7 parser KFuzzTest target
+ *
+ * Copyright 2025 Google LLC
+ */
+#include <crypto/pkcs7.h>
+#include <linux/kfuzztest.h>
+
+struct pkcs7_parse_message_arg {
+ const void *data;
+ size_t datalen;
+};
+
+FUZZ_TEST(test_pkcs7_parse_message, struct pkcs7_parse_message_arg)
+{
+ KFUZZTEST_EXPECT_NOT_NULL(pkcs7_parse_message_arg, data);
+ KFUZZTEST_ANNOTATE_ARRAY(pkcs7_parse_message_arg, data);
+ KFUZZTEST_ANNOTATE_LEN(pkcs7_parse_message_arg, datalen, data);
+
+ pkcs7_parse_message(arg->data, arg->datalen);
+}
diff --git a/crypto/asymmetric_keys/tests/rsa_helper_kfuzz.c b/crypto/asymmetric_keys/tests/rsa_helper_kfuzz.c
new file mode 100644
index 000000000000..bd29ed5e8c82
--- /dev/null
+++ b/crypto/asymmetric_keys/tests/rsa_helper_kfuzz.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * RSA key extract helper KFuzzTest targets
+ *
+ * Copyright 2025 Google LLC
+ */
+#include <linux/kfuzztest.h>
+#include <crypto/internal/rsa.h>
+
+struct rsa_parse_pub_key_arg {
+ const void *key;
+ size_t key_len;
+};
+
+FUZZ_TEST(test_rsa_parse_pub_key, struct rsa_parse_pub_key_arg)
+{
+ KFUZZTEST_EXPECT_NOT_NULL(rsa_parse_pub_key_arg, key);
+ KFUZZTEST_ANNOTATE_ARRAY(rsa_parse_pub_key_arg, key);
+ KFUZZTEST_ANNOTATE_LEN(rsa_parse_pub_key_arg, key_len, key);
+
+ struct rsa_key out;
+ rsa_parse_pub_key(&out, arg->key, arg->key_len);
+}
+
+struct rsa_parse_priv_key_arg {
+ const void *key;
+ size_t key_len;
+};
+
+FUZZ_TEST(test_rsa_parse_priv_key, struct rsa_parse_priv_key_arg)
+{
+ KFUZZTEST_EXPECT_NOT_NULL(rsa_parse_priv_key_arg, key);
+ KFUZZTEST_ANNOTATE_ARRAY(rsa_parse_priv_key_arg, key);
+ KFUZZTEST_ANNOTATE_LEN(rsa_parse_priv_key_arg, key_len, key);
+
+ struct rsa_key out;
+ rsa_parse_priv_key(&out, arg->key, arg->key_len);
+}
--
2.51.0.384.g4c02a37b29-goog
Powered by blists - more mailing lists