Linux-Hardening mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] string: Convert selftests to KUnit
@ 2024-03-01  0:26 Kees Cook
  2024-03-01  0:26 ` [PATCH v2 1/2] string: Convert selftest " Kees Cook
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Kees Cook @ 2024-03-01  0:26 UTC (permalink / raw
  To: Andy Shevchenko; +Cc: Kees Cook, linux-kernel, linux-hardening

Hi,

I realized the string selftests hadn't been converted to KUnit yet. Do that.

-Kees

 v2: rebase onto https://lore.kernel.org/r/20240229205345.93902-1-andriy.shevchenko@linux.intel.com
 v1: https://lore.kernel.org/linux-hardening/20240229233432.work.675-kees@kernel.org/

Kees Cook (2):
  string: Convert selftest to KUnit
  string: Convert helpers selftest to KUnit

 MAINTAINERS                                   |   4 +-
 lib/Kconfig.debug                             |  12 +-
 lib/Makefile                                  |   4 +-
 ...tring_helpers.c => string_helpers_kunit.c} | 177 ++++++++++--------
 lib/{test_string.c => string_kunit.c}         | 166 ++++++----------
 5 files changed, 164 insertions(+), 199 deletions(-)
 rename lib/{test-string_helpers.c => string_helpers_kunit.c} (78%)
 rename lib/{test_string.c => string_kunit.c} (54%)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/2] string: Convert selftest to KUnit
  2024-03-01  0:26 [PATCH v2 0/2] string: Convert selftests to KUnit Kees Cook
@ 2024-03-01  0:26 ` Kees Cook
  2024-03-01 11:09   ` Andy Shevchenko
  2024-03-01  0:26 ` [PATCH v2 2/2] string: Convert helpers " Kees Cook
  2024-03-01 11:22 ` [PATCH v2 0/2] string: Convert selftests " Andy Shevchenko
  2 siblings, 1 reply; 9+ messages in thread
From: Kees Cook @ 2024-03-01  0:26 UTC (permalink / raw
  To: Andy Shevchenko; +Cc: Kees Cook, linux-hardening, linux-kernel

Convert test_string.c to KUnit so it can be easily run with everything
else.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
Cc: Andy Shevchenko <andy@kernel.org>
Cc: linux-hardening@vger.kernel.org
---
 MAINTAINERS                           |   2 +-
 lib/Kconfig.debug                     |   6 +-
 lib/Makefile                          |   2 +-
 lib/{test_string.c => string_kunit.c} | 166 +++++++++-----------------
 4 files changed, 61 insertions(+), 115 deletions(-)
 rename lib/{test_string.c => string_kunit.c} (54%)

diff --git a/MAINTAINERS b/MAINTAINERS
index cd651c4df019..9f1f68cccd6a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8976,9 +8976,9 @@ F:	include/linux/string.h
 F:	include/linux/string_choices.h
 F:	include/linux/string_helpers.h
 F:	lib/string.c
+F:	lib/string_kunit.c
 F:	lib/string_helpers.c
 F:	lib/test-string_helpers.c
-F:	lib/test_string.c
 F:	scripts/coccinelle/api/string_choices.cocci
 
 GENERIC UIO DRIVER FOR PCI DEVICES
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 4e2febe3b568..406cdf353488 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2352,8 +2352,10 @@ config ASYNC_RAID6_TEST
 config TEST_HEXDUMP
 	tristate "Test functions located in the hexdump module at runtime"
 
-config STRING_SELFTEST
-	tristate "Test string functions at runtime"
+config STRING_KUNIT_TEST
+	tristate "KUnit test string functions at runtime" if !KUNIT_ALL_TESTS
+	depends on KUNIT
+	default KUNIT_ALL_TESTS
 
 config TEST_STRING_HELPERS
 	tristate "Test functions located in the string_helpers module at runtime"
diff --git a/lib/Makefile b/lib/Makefile
index eae87c41b22b..946277c37831 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -49,7 +49,7 @@ obj-y += bcd.o sort.o parser.o debug_locks.o random32.o \
 	 percpu-refcount.o rhashtable.o base64.o \
 	 once.o refcount.o rcuref.o usercopy.o errseq.o bucket_locks.o \
 	 generic-radix-tree.o bitmap-str.o
-obj-$(CONFIG_STRING_SELFTEST) += test_string.o
+obj-$(CONFIG_STRING_KUNIT_TEST) += string_kunit.o
 obj-y += string_helpers.o
 obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
 obj-y += hexdump.o
diff --git a/lib/test_string.c b/lib/string_kunit.c
similarity index 54%
rename from lib/test_string.c
rename to lib/string_kunit.c
index c5cb92fb710e..bbb54ac11f7b 100644
--- a/lib/test_string.c
+++ b/lib/string_kunit.c
@@ -1,17 +1,23 @@
 // SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Test cases for string functions.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <kunit/test.h>
 #include <linux/module.h>
 #include <linux/printk.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 
-static __init int memset16_selftest(void)
+static void test_memset16(struct kunit *test)
 {
 	unsigned i, j, k;
 	u16 v, *p;
 
 	p = kmalloc(256 * 2 * 2, GFP_KERNEL);
-	if (!p)
-		return -1;
+	KUNIT_ASSERT_NOT_NULL(test, p);
 
 	for (i = 0; i < 256; i++) {
 		for (j = 0; j < 256; j++) {
@@ -20,34 +26,28 @@ static __init int memset16_selftest(void)
 			for (k = 0; k < 512; k++) {
 				v = p[k];
 				if (k < i) {
-					if (v != 0xa1a1)
-						goto fail;
+					KUNIT_EXPECT_EQ(test, v, 0xa1a1);
 				} else if (k < i + j) {
-					if (v != 0xb1b2)
-						goto fail;
+					KUNIT_EXPECT_EQ(test, v, 0xb1b2);
 				} else {
-					if (v != 0xa1a1)
-						goto fail;
+					KUNIT_EXPECT_EQ(test, v, 0xa1a1);
 				}
 			}
 		}
 	}
 
-fail:
 	kfree(p);
 	if (i < 256)
-		return (i << 24) | (j << 16) | k | 0x8000;
-	return 0;
+		KUNIT_EXPECT_EQ(test, 0, (i << 24) | (j << 16) | k | 0x8000);
 }
 
-static __init int memset32_selftest(void)
+static void test_memset32(struct kunit *test)
 {
 	unsigned i, j, k;
 	u32 v, *p;
 
 	p = kmalloc(256 * 2 * 4, GFP_KERNEL);
-	if (!p)
-		return -1;
+	KUNIT_ASSERT_NOT_NULL(test, p);
 
 	for (i = 0; i < 256; i++) {
 		for (j = 0; j < 256; j++) {
@@ -56,34 +56,28 @@ static __init int memset32_selftest(void)
 			for (k = 0; k < 512; k++) {
 				v = p[k];
 				if (k < i) {
-					if (v != 0xa1a1a1a1)
-						goto fail;
+					KUNIT_EXPECT_EQ(test, v, 0xa1a1a1a1);
 				} else if (k < i + j) {
-					if (v != 0xb1b2b3b4)
-						goto fail;
+					KUNIT_EXPECT_EQ(test, v, 0xb1b2b3b4);
 				} else {
-					if (v != 0xa1a1a1a1)
-						goto fail;
+					KUNIT_EXPECT_EQ(test, v, 0xa1a1a1a1);
 				}
 			}
 		}
 	}
 
-fail:
 	kfree(p);
 	if (i < 256)
-		return (i << 24) | (j << 16) | k | 0x8000;
-	return 0;
+		KUNIT_EXPECT_EQ(test, 0, (i << 24) | (j << 16) | k | 0x8000);
 }
 
-static __init int memset64_selftest(void)
+static void test_memset64(struct kunit *test)
 {
 	unsigned i, j, k;
 	u64 v, *p;
 
 	p = kmalloc(256 * 2 * 8, GFP_KERNEL);
-	if (!p)
-		return -1;
+	KUNIT_ASSERT_NOT_NULL(test, p);
 
 	for (i = 0; i < 256; i++) {
 		for (j = 0; j < 256; j++) {
@@ -92,27 +86,22 @@ static __init int memset64_selftest(void)
 			for (k = 0; k < 512; k++) {
 				v = p[k];
 				if (k < i) {
-					if (v != 0xa1a1a1a1a1a1a1a1ULL)
-						goto fail;
+					KUNIT_EXPECT_EQ(test, v, 0xa1a1a1a1a1a1a1a1ULL);
 				} else if (k < i + j) {
-					if (v != 0xb1b2b3b4b5b6b7b8ULL)
-						goto fail;
+					KUNIT_EXPECT_EQ(test, v, 0xb1b2b3b4b5b6b7b8ULL);
 				} else {
-					if (v != 0xa1a1a1a1a1a1a1a1ULL)
-						goto fail;
+					KUNIT_EXPECT_EQ(test, v, 0xa1a1a1a1a1a1a1a1ULL);
 				}
 			}
 		}
 	}
 
-fail:
 	kfree(p);
 	if (i < 256)
-		return (i << 24) | (j << 16) | k | 0x8000;
-	return 0;
+		KUNIT_EXPECT_EQ(test, 0, (i << 24) | (j << 16) | k | 0x8000);
 }
 
-static __init int strchr_selftest(void)
+static void test_strchr(struct kunit *test)
 {
 	const char *test_string = "abcdefghijkl";
 	const char *empty_string = "";
@@ -121,26 +110,20 @@ static __init int strchr_selftest(void)
 
 	for (i = 0; i < strlen(test_string) + 1; i++) {
 		result = strchr(test_string, test_string[i]);
-		if (result - test_string != i)
-			return i + 'a';
+		KUNIT_ASSERT_EQ(test, result - test_string, i);
 	}
 
 	result = strchr(empty_string, '\0');
-	if (result != empty_string)
-		return 0x101;
+	KUNIT_ASSERT_PTR_EQ(test, result, empty_string);
 
 	result = strchr(empty_string, 'a');
-	if (result)
-		return 0x102;
+	KUNIT_ASSERT_NULL(test, result);
 
 	result = strchr(test_string, 'z');
-	if (result)
-		return 0x103;
-
-	return 0;
+	KUNIT_ASSERT_NULL(test, result);
 }
 
-static __init int strnchr_selftest(void)
+static void test_strnchr(struct kunit *test)
 {
 	const char *test_string = "abcdefghijkl";
 	const char *empty_string = "";
@@ -153,33 +136,27 @@ static __init int strnchr_selftest(void)
 			if (j <= i) {
 				if (!result)
 					continue;
-				return ((i + 'a') << 8) | j;
+				KUNIT_ASSERT_EQ(test, 0, 1);
 			}
 			if (result - test_string != i)
-				return ((i + 'a') << 8) | j;
+				KUNIT_ASSERT_EQ(test, 0, 1);
 		}
 	}
 
 	result = strnchr(empty_string, 0, '\0');
-	if (result)
-		return 0x10001;
+	KUNIT_ASSERT_NULL(test, result);
 
 	result = strnchr(empty_string, 1, '\0');
-	if (result != empty_string)
-		return 0x10002;
+	KUNIT_ASSERT_PTR_EQ(test, result, empty_string);
 
 	result = strnchr(empty_string, 1, 'a');
-	if (result)
-		return 0x10003;
+	KUNIT_ASSERT_NULL(test, result);
 
 	result = strnchr(NULL, 0, '\0');
-	if (result)
-		return 0x10004;
-
-	return 0;
+	KUNIT_ASSERT_NULL(test, result);
 }
 
-static __init int strspn_selftest(void)
+static void test_strspn(struct kunit *test)
 {
 	static const struct strspn_test {
 		const char str[16];
@@ -187,7 +164,7 @@ static __init int strspn_selftest(void)
 		const char reject[16];
 		unsigned a;
 		unsigned r;
-	} tests[] __initconst = {
+	} tests[] = {
 		{ "foobar", "", "", 0, 6 },
 		{ "abba", "abc", "ABBA", 4, 4 },
 		{ "abba", "a", "b", 1, 1 },
@@ -198,60 +175,27 @@ static __init int strspn_selftest(void)
 
 	for (i = 0; i < ARRAY_SIZE(tests); ++i, ++s) {
 		res = strspn(s->str, s->accept);
-		if (res != s->a)
-			return 0x100 + 2*i;
+		KUNIT_ASSERT_EQ(test, res, s->a);
 		res = strcspn(s->str, s->reject);
-		if (res != s->r)
-			return 0x100 + 2*i + 1;
+		KUNIT_ASSERT_EQ(test, res, s->r);
 	}
-	return 0;
-}
-
-static __exit void string_selftest_remove(void)
-{
 }
 
-static __init int string_selftest_init(void)
-{
-	int test, subtest;
-
-	test = 1;
-	subtest = memset16_selftest();
-	if (subtest)
-		goto fail;
-
-	test = 2;
-	subtest = memset32_selftest();
-	if (subtest)
-		goto fail;
-
-	test = 3;
-	subtest = memset64_selftest();
-	if (subtest)
-		goto fail;
+static struct kunit_case string_test_cases[] = {
+	KUNIT_CASE(test_memset16),
+	KUNIT_CASE(test_memset32),
+	KUNIT_CASE(test_memset64),
+	KUNIT_CASE(test_strchr),
+	KUNIT_CASE(test_strnchr),
+	KUNIT_CASE(test_strspn),
+	{}
+};
 
-	test = 4;
-	subtest = strchr_selftest();
-	if (subtest)
-		goto fail;
+static struct kunit_suite string_test_suite = {
+	.name = "string",
+	.test_cases = string_test_cases,
+};
 
-	test = 5;
-	subtest = strnchr_selftest();
-	if (subtest)
-		goto fail;
-
-	test = 6;
-	subtest = strspn_selftest();
-	if (subtest)
-		goto fail;
-
-	pr_info("String selftests succeeded\n");
-	return 0;
-fail:
-	pr_crit("String selftest failure %d.%08x\n", test, subtest);
-	return 0;
-}
+kunit_test_suites(&string_test_suite);
 
-module_init(string_selftest_init);
-module_exit(string_selftest_remove);
 MODULE_LICENSE("GPL v2");
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/2] string: Convert helpers selftest to KUnit
  2024-03-01  0:26 [PATCH v2 0/2] string: Convert selftests to KUnit Kees Cook
  2024-03-01  0:26 ` [PATCH v2 1/2] string: Convert selftest " Kees Cook
@ 2024-03-01  0:26 ` Kees Cook
  2024-03-01 11:20   ` Andy Shevchenko
  2024-03-01 11:22 ` [PATCH v2 0/2] string: Convert selftests " Andy Shevchenko
  2 siblings, 1 reply; 9+ messages in thread
From: Kees Cook @ 2024-03-01  0:26 UTC (permalink / raw
  To: Andy Shevchenko; +Cc: Kees Cook, Kent Overstreet, linux-hardening, linux-kernel

Convert test-string_helpers.c to KUnit so it can be easily run with
everything else.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
Cc: Andy Shevchenko <andy@kernel.org>
Cc: Kent Overstreet <kent.overstreet@linux.dev>
Cc: linux-hardening@vger.kernel.org
---
 MAINTAINERS                                   |   2 +-
 lib/Kconfig.debug                             |   6 +-
 lib/Makefile                                  |   2 +-
 ...tring_helpers.c => string_helpers_kunit.c} | 177 ++++++++++--------
 4 files changed, 103 insertions(+), 84 deletions(-)
 rename lib/{test-string_helpers.c => string_helpers_kunit.c} (78%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9f1f68cccd6a..f3f26d2d4ffb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8978,7 +8978,7 @@ F:	include/linux/string_helpers.h
 F:	lib/string.c
 F:	lib/string_kunit.c
 F:	lib/string_helpers.c
-F:	lib/test-string_helpers.c
+F:	lib/string_helpers_kunit.c
 F:	scripts/coccinelle/api/string_choices.cocci
 
 GENERIC UIO DRIVER FOR PCI DEVICES
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 406cdf353488..5429e6f170f3 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2357,8 +2357,10 @@ config STRING_KUNIT_TEST
 	depends on KUNIT
 	default KUNIT_ALL_TESTS
 
-config TEST_STRING_HELPERS
-	tristate "Test functions located in the string_helpers module at runtime"
+config STRING_HELPERS_KUNIT_TEST
+	tristate "KUnit test string helpers at runtime" if !KUNIT_ALL_TESTS
+	depends on KUNIT
+	default KUNIT_ALL_TESTS
 
 config TEST_KSTRTOX
 	tristate "Test kstrto*() family of functions at runtime"
diff --git a/lib/Makefile b/lib/Makefile
index 946277c37831..97c42e38046f 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -51,7 +51,7 @@ obj-y += bcd.o sort.o parser.o debug_locks.o random32.o \
 	 generic-radix-tree.o bitmap-str.o
 obj-$(CONFIG_STRING_KUNIT_TEST) += string_kunit.o
 obj-y += string_helpers.o
-obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
+obj-$(CONFIG_STRING_HELPERS_KUNIT_TEST) += string_helpers_kunit.o
 obj-y += hexdump.o
 obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
 obj-y += kstrtox.o
diff --git a/lib/test-string_helpers.c b/lib/string_helpers_kunit.c
similarity index 78%
rename from lib/test-string_helpers.c
rename to lib/string_helpers_kunit.c
index dce67698297b..1fed4fa38f97 100644
--- a/lib/test-string_helpers.c
+++ b/lib/string_helpers_kunit.c
@@ -3,8 +3,9 @@
  */
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/array_size.h>
 #include <linux/init.h>
+#include <kunit/test.h>
+#include <linux/array_size.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -12,13 +13,21 @@
 #include <linux/string.h>
 #include <linux/string_helpers.h>
 
-static __init bool test_string_check_buf(const char *name, unsigned int flags,
-					 char *in, size_t p,
-					 char *out_real, size_t q_real,
-					 char *out_test, size_t q_test)
+static void test_string_check_buf(struct kunit *test,
+				  const char *name, unsigned int flags,
+				  char *in, size_t p,
+				  char *out_real, size_t q_real,
+				  char *out_test, size_t q_test)
 {
-	if (q_real == q_test && !memcmp(out_test, out_real, q_test))
-		return true;
+	int result;
+
+	KUNIT_EXPECT_EQ(test, q_real, q_test);
+
+	result = memcmp(out_test, out_real, q_test);
+	KUNIT_EXPECT_EQ(test, 0, result);
+
+	if (q_real == q_test && result == 0)
+		return;
 
 	pr_warn("Test '%s' failed: flags = %#x\n", name, flags);
 
@@ -28,8 +37,6 @@ static __init bool test_string_check_buf(const char *name, unsigned int flags,
 		       out_test, q_test, true);
 	print_hex_dump(KERN_WARNING, "Got: ", DUMP_PREFIX_NONE, 16, 1,
 		       out_real, q_real, true);
-
-	return false;
 }
 
 struct test_string {
@@ -38,7 +45,7 @@ struct test_string {
 	unsigned int flags;
 };
 
-static const struct test_string strings[] __initconst = {
+static const struct test_string strings[] = {
 	{
 		.in = "\\f\\ \\n\\r\\t\\v",
 		.out = "\f\\ \n\r\t\v",
@@ -61,8 +68,9 @@ static const struct test_string strings[] __initconst = {
 	},
 };
 
-static void __init test_string_unescape(const char *name, unsigned int flags,
-					bool inplace)
+static void test_string_unescape(struct kunit *test,
+				 const char *name, unsigned int flags,
+				 bool inplace)
 {
 	int q_real = 256;
 	char *in = kmalloc(q_real, GFP_KERNEL);
@@ -104,7 +112,7 @@ static void __init test_string_unescape(const char *name, unsigned int flags,
 		q_real = string_unescape(in, out_real, q_real, flags);
 	}
 
-	test_string_check_buf(name, flags, in, p - 1, out_real, q_real,
+	test_string_check_buf(test, name, flags, in, p - 1, out_real, q_real,
 			      out_test, q_test);
 out:
 	kfree(out_real);
@@ -124,7 +132,7 @@ struct test_string_2 {
 };
 
 #define	TEST_STRING_2_DICT_0		NULL
-static const struct test_string_2 escape0[] __initconst = {{
+static const struct test_string_2 escape0[] = {{
 	.in = "\f\\ \n\r\t\v",
 	.s1 = {{
 		.out = "\\f\\ \\n\\r\\t\\v",
@@ -222,7 +230,7 @@ static const struct test_string_2 escape0[] __initconst = {{
 }};
 
 #define	TEST_STRING_2_DICT_1		"b\\ \t\r\xCF"
-static const struct test_string_2 escape1[] __initconst = {{
+static const struct test_string_2 escape1[] = {{
 	.in = "\f\\ \n\r\t\v",
 	.s1 = {{
 		.out = "\f\\134\\040\n\\015\\011\v",
@@ -359,7 +367,7 @@ static const struct test_string_2 escape1[] __initconst = {{
 	/* terminator */
 }};
 
-static const struct test_string strings_upper[] __initconst = {
+static const struct test_string strings_upper[] = {
 	{
 		.in = "abcdefgh1234567890test",
 		.out = "ABCDEFGH1234567890TEST",
@@ -370,7 +378,7 @@ static const struct test_string strings_upper[] __initconst = {
 	},
 };
 
-static const struct test_string strings_lower[] __initconst = {
+static const struct test_string strings_lower[] = {
 	{
 		.in = "ABCDEFGH1234567890TEST",
 		.out = "abcdefgh1234567890test",
@@ -381,8 +389,8 @@ static const struct test_string strings_lower[] __initconst = {
 	},
 };
 
-static __init const char *test_string_find_match(const struct test_string_2 *s2,
-						 unsigned int flags)
+static const char *test_string_find_match(const struct test_string_2 *s2,
+					  unsigned int flags)
 {
 	const struct test_string_1 *s1 = s2->s1;
 	unsigned int i;
@@ -403,21 +411,20 @@ static __init const char *test_string_find_match(const struct test_string_2 *s2,
 	return NULL;
 }
 
-static __init void
-test_string_escape_overflow(const char *in, int p, unsigned int flags, const char *esc,
+static void
+test_string_escape_overflow(struct kunit *test,
+			    const char *in, int p, unsigned int flags, const char *esc,
 			    int q_test, const char *name)
 {
 	int q_real;
 
 	q_real = string_escape_mem(in, p, NULL, 0, flags, esc);
-	if (q_real != q_test)
-		pr_warn("Test '%s' failed: flags = %#x, osz = 0, expected %d, got %d\n",
-			name, flags, q_test, q_real);
+	KUNIT_EXPECT_EQ(test, q_real, q_test);
 }
 
-static __init void test_string_escape(const char *name,
-				      const struct test_string_2 *s2,
-				      unsigned int flags, const char *esc)
+static void test_string_escape(struct kunit *test, const char *name,
+			       const struct test_string_2 *s2,
+			       unsigned int flags, const char *esc)
 {
 	size_t out_size = 512;
 	char *out_test = kmalloc(out_size, GFP_KERNEL);
@@ -463,10 +470,10 @@ static __init void test_string_escape(const char *name,
 
 	q_real = string_escape_mem(in, p, out_real, out_size, flags, esc);
 
-	test_string_check_buf(name, flags, in, p, out_real, q_real, out_test,
+	test_string_check_buf(test, name, flags, in, p, out_real, q_real, out_test,
 			      q_test);
 
-	test_string_escape_overflow(in, p, flags, esc, q_test, name);
+	test_string_escape_overflow(test, in, p, flags, esc, q_test, name);
 
 out:
 	kfree(in);
@@ -475,22 +482,26 @@ static __init void test_string_escape(const char *name,
 }
 
 #define string_get_size_maxbuf 16
-#define test_string_get_size_one(size, blk_size, exp_result10, exp_result2)    \
-	do {                                                                   \
-		BUILD_BUG_ON(sizeof(exp_result10) >= string_get_size_maxbuf);  \
-		BUILD_BUG_ON(sizeof(exp_result2) >= string_get_size_maxbuf);   \
-		__test_string_get_size((size), (blk_size), (exp_result10),     \
-				       (exp_result2));                         \
+#define test_string_get_size_one(size, blk_size, exp_result10, exp_result2)      \
+	do {                                                                     \
+		BUILD_BUG_ON(sizeof(exp_result10) >= string_get_size_maxbuf);    \
+		BUILD_BUG_ON(sizeof(exp_result2) >= string_get_size_maxbuf);     \
+		__test_string_get_size(test, (size), (blk_size), (exp_result10), \
+				       (exp_result2));                           \
 	} while (0)
 
 
-static __init void test_string_get_size_check(const char *units,
-					      const char *exp,
-					      char *res,
-					      const u64 size,
-					      const u64 blk_size)
+static void test_string_get_size_check(struct kunit *test,
+				       const char *units,
+				       const char *exp,
+				       char *res,
+				       const u64 size,
+				       const u64 blk_size)
 {
-	if (!memcmp(res, exp, strlen(exp) + 1))
+	int result = memcmp(res, exp, strlen(exp) + 1);
+
+	KUNIT_EXPECT_EQ(test, 0, result);
+	if (!result)
 		return;
 
 	res[string_get_size_maxbuf - 1] = '\0';
@@ -501,7 +512,7 @@ static __init void test_string_get_size_check(const char *units,
 	pr_warn("expected: '%s', got '%s'\n", exp, res);
 }
 
-static __init void __strchrcut(char *dst, const char *src, const char *cut)
+static void __strchrcut(char *dst, const char *src, const char *cut)
 {
 	const char *from = src;
 	size_t len;
@@ -515,11 +526,12 @@ static __init void __strchrcut(char *dst, const char *src, const char *cut)
 	*dst = '\0';
 }
 
-static __init void __test_string_get_size_one(const u64 size, const u64 blk_size,
-					      const char *exp_result10,
-					      const char *exp_result2,
-					      enum string_size_units units,
-					      const char *cut)
+static void __test_string_get_size_one(struct kunit *test,
+				       const u64 size, const u64 blk_size,
+				       const char *exp_result10,
+				       const char *exp_result2,
+				       enum string_size_units units,
+				       const char *cut)
 {
 	char buf10[string_get_size_maxbuf];
 	char buf2[string_get_size_maxbuf];
@@ -537,13 +549,14 @@ static __init void __test_string_get_size_one(const u64 size, const u64 blk_size
 	string_get_size(size, blk_size, STRING_UNITS_10 | units, buf10, sizeof(buf10));
 	string_get_size(size, blk_size, STRING_UNITS_2 | units, buf2, sizeof(buf2));
 
-	test_string_get_size_check(prefix10, exp10, buf10, size, blk_size);
-	test_string_get_size_check(prefix2, exp2, buf2, size, blk_size);
+	test_string_get_size_check(test, prefix10, exp10, buf10, size, blk_size);
+	test_string_get_size_check(test, prefix2, exp2, buf2, size, blk_size);
 }
 
-static __init void __test_string_get_size(const u64 size, const u64 blk_size,
-					  const char *exp_result10,
-					  const char *exp_result2)
+static void __test_string_get_size(struct kunit *test,
+				   const u64 size, const u64 blk_size,
+				   const char *exp_result10,
+				   const char *exp_result2)
 {
 	struct {
 		enum string_size_units units;
@@ -557,12 +570,13 @@ static __init void __test_string_get_size(const u64 size, const u64 blk_size,
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(get_size_test_cases); i++)
-		__test_string_get_size_one(size, blk_size, exp_result10, exp_result2,
+		__test_string_get_size_one(test, size, blk_size,
+					   exp_result10, exp_result2,
 					   get_size_test_cases[i].units,
 					   get_size_test_cases[i].cut);
 }
 
-static __init void test_string_get_size(void)
+static void test_get_size(struct kunit *test)
 {
 	/* small values */
 	test_string_get_size_one(0, 512, "0 B", "0 B");
@@ -582,7 +596,7 @@ static __init void test_string_get_size(void)
 	test_string_get_size_one(4096, U64_MAX, "75.6 ZB", "64.0 ZiB");
 }
 
-static void __init test_string_upper_lower(void)
+static void test_upper_lower(struct kunit *test)
 {
 	char *dst;
 	int i;
@@ -590,65 +604,68 @@ static void __init test_string_upper_lower(void)
 	for (i = 0; i < ARRAY_SIZE(strings_upper); i++) {
 		const char *s = strings_upper[i].in;
 		int len = strlen(strings_upper[i].in) + 1;
+		int result;
 
 		dst = kmalloc(len, GFP_KERNEL);
-		if (!dst)
-			return;
+		KUNIT_ASSERT_NOT_NULL(test, dst);
 
 		string_upper(dst, s);
-		if (memcmp(dst, strings_upper[i].out, len)) {
+		result = memcmp(dst, strings_upper[i].out, len);
+		KUNIT_EXPECT_EQ(test, 0, result);
+		if (result)
 			pr_warn("Test 'string_upper' failed : expected %s, got %s!\n",
 				strings_upper[i].out, dst);
-			kfree(dst);
-			return;
-		}
 		kfree(dst);
 	}
 
 	for (i = 0; i < ARRAY_SIZE(strings_lower); i++) {
 		const char *s = strings_lower[i].in;
 		int len = strlen(strings_lower[i].in) + 1;
+		int result;
 
 		dst = kmalloc(len, GFP_KERNEL);
-		if (!dst)
-			return;
+		KUNIT_ASSERT_NOT_NULL(test, dst);
 
 		string_lower(dst, s);
-		if (memcmp(dst, strings_lower[i].out, len)) {
+		result = memcmp(dst, strings_lower[i].out, len);
+		KUNIT_EXPECT_EQ(test, 0, result);
+		if (result)
 			pr_warn("Test 'string_lower failed : : expected %s, got %s!\n",
 				strings_lower[i].out, dst);
-			kfree(dst);
-			return;
-		}
 		kfree(dst);
 	}
 }
 
-static int __init test_string_helpers_init(void)
+static void test_unescape(struct kunit *test)
 {
 	unsigned int i;
 
-	pr_info("Running tests...\n");
 	for (i = 0; i < UNESCAPE_ALL_MASK + 1; i++)
-		test_string_unescape("unescape", i, false);
-	test_string_unescape("unescape inplace",
+		test_string_unescape(test, "unescape", i, false);
+	test_string_unescape(test, "unescape inplace",
 			     get_random_u32_below(UNESCAPE_ALL_MASK + 1), true);
 
 	/* Without dictionary */
 	for (i = 0; i < ESCAPE_ALL_MASK + 1; i++)
-		test_string_escape("escape 0", escape0, i, TEST_STRING_2_DICT_0);
+		test_string_escape(test, "escape 0", escape0, i, TEST_STRING_2_DICT_0);
 
 	/* With dictionary */
 	for (i = 0; i < ESCAPE_ALL_MASK + 1; i++)
-		test_string_escape("escape 1", escape1, i, TEST_STRING_2_DICT_1);
+		test_string_escape(test, "escape 1", escape1, i, TEST_STRING_2_DICT_1);
+}
 
-	/* Test string_get_size() */
-	test_string_get_size();
+static struct kunit_case string_helpers_test_cases[] = {
+	KUNIT_CASE(test_get_size),
+	KUNIT_CASE(test_upper_lower),
+	KUNIT_CASE(test_unescape),
+	{}
+};
 
-	/* Test string upper(), string_lower() */
-	test_string_upper_lower();
+static struct kunit_suite string_helpers_test_suite = {
+	.name = "string_helpers",
+	.test_cases = string_helpers_test_cases,
+};
+
+kunit_test_suites(&string_helpers_test_suite);
 
-	return -EINVAL;
-}
-module_init(test_string_helpers_init);
 MODULE_LICENSE("Dual BSD/GPL");
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/2] string: Convert selftest to KUnit
  2024-03-01  0:26 ` [PATCH v2 1/2] string: Convert selftest " Kees Cook
@ 2024-03-01 11:09   ` Andy Shevchenko
  2024-03-01 17:25     ` Kees Cook
  0 siblings, 1 reply; 9+ messages in thread
From: Andy Shevchenko @ 2024-03-01 11:09 UTC (permalink / raw
  To: Kees Cook; +Cc: Andy Shevchenko, linux-hardening, linux-kernel

On Fri, Mar 1, 2024 at 2:26 AM Kees Cook <keescook@chromium.org> wrote:
>
> Convert test_string.c to KUnit so it can be easily run with everything
> else.

Have you run it?

...

>         if (i < 256)
> -               return (i << 24) | (j << 16) | k | 0x8000;
> -       return 0;
> +               KUNIT_EXPECT_EQ(test, 0, (i << 24) | (j << 16) | k | 0x8000);

First of all, this special value encodes the problematic patterns, so
you missed proper messaging.
Second, the returned value has a constant, how do you expect 0 to be
equal to something (guaranteed not to be 0)?

This needs a good rethink of what you should do in the KUnit approach.

...

> +               KUNIT_EXPECT_EQ(test, 0, (i << 24) | (j << 16) | k | 0x8000);

Ditto.

...

> +               KUNIT_EXPECT_EQ(test, 0, (i << 24) | (j << 16) | k | 0x8000);

Ditto.

...

>         for (i = 0; i < strlen(test_string) + 1; i++) {
>                 result = strchr(test_string, test_string[i]);
> -               if (result - test_string != i)
> -                       return i + 'a';
> +               KUNIT_ASSERT_EQ(test, result - test_string, i);

In a similar way, all returned values are *special*, you really need
to think about them before converting to a simple (and sometimes
wrong) checks)

...

I dunno if KUnit has a fault ejection simulation. It should, in order
to be sure that test cases are fine when they fail.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/2] string: Convert helpers selftest to KUnit
  2024-03-01  0:26 ` [PATCH v2 2/2] string: Convert helpers " Kees Cook
@ 2024-03-01 11:20   ` Andy Shevchenko
  2024-03-01 20:29     ` Kees Cook
  0 siblings, 1 reply; 9+ messages in thread
From: Andy Shevchenko @ 2024-03-01 11:20 UTC (permalink / raw
  To: Kees Cook; +Cc: Andy Shevchenko, Kent Overstreet, linux-hardening, linux-kernel

On Fri, Mar 1, 2024 at 2:26 AM Kees Cook <keescook@chromium.org> wrote:
>
> Convert test-string_helpers.c to KUnit so it can be easily run with
> everything else.

...

> -#include <linux/array_size.h>
>  #include <linux/init.h>
> +#include <kunit/test.h>

I know the order is broken here, but don't make it worse, please. And
stick with one schema where to put kunit/test.h always before
everything else and somewhere else (like always after linux/*).

> +#include <linux/array_size.h>
>  #include <linux/kernel.h>
>  #include <linux/slab.h>
>  #include <linux/module.h>

...

> +static void test_string_check_buf(struct kunit *test,
> +                                 const char *name, unsigned int flags,
> +                                 char *in, size_t p,
> +                                 char *out_real, size_t q_real,
> +                                 char *out_test, size_t q_test)
>  {
> -       if (q_real == q_test && !memcmp(out_test, out_real, q_test))
> -               return true;
> +       int result;
> +
> +       KUNIT_EXPECT_EQ(test, q_real, q_test);

This needs a message.

> +       result = memcmp(out_test, out_real, q_test);

> +       KUNIT_EXPECT_EQ(test, 0, result);

Why do we need this assertion? We have a dump below to show what's wrong.

> +       if (q_real == q_test && result == 0)
> +               return;

I'm not sure this is an equivalent change. IIRC KUnit assertions do
not continue on failure. (Long time last time I run KUnit test)

>
>         pr_warn("Test '%s' failed: flags = %#x\n", name, flags);
>
> @@ -28,8 +37,6 @@ static __init bool test_string_check_buf(const char *name, unsigned int flags,
>                        out_test, q_test, true);
>         print_hex_dump(KERN_WARNING, "Got: ", DUMP_PREFIX_NONE, 16, 1,
>                        out_real, q_real, true);
> -
> -       return false;
>  }

...

> +static void
> +test_string_escape_overflow(struct kunit *test,
> +                           const char *in, int p, unsigned int flags, const char *esc,
>                             int q_test, const char *name)
>  {
>         int q_real;
>
>         q_real = string_escape_mem(in, p, NULL, 0, flags, esc);
> -       if (q_real != q_test)
> -               pr_warn("Test '%s' failed: flags = %#x, osz = 0, expected %d, got %d\n",
> -                       name, flags, q_test, q_real);
> +       KUNIT_EXPECT_EQ(test, q_real, q_test);

You killed the message, not good.

>  }

...

> +#define test_string_get_size_one(size, blk_size, exp_result10, exp_result2)      \
> +       do {                                                                     \
> +               BUILD_BUG_ON(sizeof(exp_result10) >= string_get_size_maxbuf);    \
> +               BUILD_BUG_ON(sizeof(exp_result2) >= string_get_size_maxbuf);     \

No analogous assertions in KUnit?

> +               __test_string_get_size(test, (size), (blk_size), (exp_result10), \
> +                                      (exp_result2));                           \
>         } while (0)

...

>  {
> -       if (!memcmp(res, exp, strlen(exp) + 1))
> +       int result = memcmp(res, exp, strlen(exp) + 1);

> +       KUNIT_EXPECT_EQ(test, 0, result);

As per above, what's the added value of this assertion?

> +       if (!result)
>                 return;

...

> @@ -590,65 +604,68 @@ static void __init test_string_upper_lower(void)
>         for (i = 0; i < ARRAY_SIZE(strings_upper); i++) {
>                 const char *s = strings_upper[i].in;
>                 int len = strlen(strings_upper[i].in) + 1;
> +               int result;
>
>                 dst = kmalloc(len, GFP_KERNEL);
> -               if (!dst)
> -                       return;
> +               KUNIT_ASSERT_NOT_NULL(test, dst);
>
>                 string_upper(dst, s);
> -               if (memcmp(dst, strings_upper[i].out, len)) {
> +               result = memcmp(dst, strings_upper[i].out, len);
> +               KUNIT_EXPECT_EQ(test, 0, result);

Ditto.

> +               if (result)
>                         pr_warn("Test 'string_upper' failed : expected %s, got %s!\n",
>                                 strings_upper[i].out, dst);
> -                       kfree(dst);
> -                       return;
> -               }
>                 kfree(dst);
>         }
>
>         for (i = 0; i < ARRAY_SIZE(strings_lower); i++) {
>                 const char *s = strings_lower[i].in;
>                 int len = strlen(strings_lower[i].in) + 1;
> +               int result;
>
>                 dst = kmalloc(len, GFP_KERNEL);
> -               if (!dst)
> -                       return;
> +               KUNIT_ASSERT_NOT_NULL(test, dst);
>
>                 string_lower(dst, s);
> -               if (memcmp(dst, strings_lower[i].out, len)) {
> +               result = memcmp(dst, strings_lower[i].out, len);
> +               KUNIT_EXPECT_EQ(test, 0, result);

Ditto.

> +               if (result)
>                         pr_warn("Test 'string_lower failed : : expected %s, got %s!\n",
>                                 strings_lower[i].out, dst);
> -                       kfree(dst);
> -                       return;
> -               }
>                 kfree(dst);
>         }
>  }


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 0/2] string: Convert selftests to KUnit
  2024-03-01  0:26 [PATCH v2 0/2] string: Convert selftests to KUnit Kees Cook
  2024-03-01  0:26 ` [PATCH v2 1/2] string: Convert selftest " Kees Cook
  2024-03-01  0:26 ` [PATCH v2 2/2] string: Convert helpers " Kees Cook
@ 2024-03-01 11:22 ` Andy Shevchenko
  2 siblings, 0 replies; 9+ messages in thread
From: Andy Shevchenko @ 2024-03-01 11:22 UTC (permalink / raw
  To: Kees Cook, Rasmus Villemoes
  Cc: Andy Shevchenko, linux-kernel, linux-hardening

On Fri, Mar 1, 2024 at 2:26 AM Kees Cook <keescook@chromium.org> wrote:
>
> Hi,
>
> I realized the string selftests hadn't been converted to KUnit yet. Do that.

IIRC last time somebody wanted to do that KUnit was completely sucking
in supporting the cases we need in these files. (I mean proper
messaging when we need to dump the expected and resulting data). And
please Cc Rasmus as well.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/2] string: Convert selftest to KUnit
  2024-03-01 11:09   ` Andy Shevchenko
@ 2024-03-01 17:25     ` Kees Cook
  2024-03-01 17:29       ` Andy Shevchenko
  0 siblings, 1 reply; 9+ messages in thread
From: Kees Cook @ 2024-03-01 17:25 UTC (permalink / raw
  To: Andy Shevchenko; +Cc: Andy Shevchenko, linux-hardening, linux-kernel

On Fri, Mar 01, 2024 at 01:09:27PM +0200, Andy Shevchenko wrote:
> On Fri, Mar 1, 2024 at 2:26 AM Kees Cook <keescook@chromium.org> wrote:
> >
> > Convert test_string.c to KUnit so it can be easily run with everything
> > else.
> 
> Have you run it?

Yes:

$ ./tools/testing/kunit/kunit.py run string

[09:21:32] Starting KUnit Kernel (1/1)...
[09:21:32] ============================================================
[09:21:32] =================== string (6 subtests) ====================
[09:21:32] [PASSED] test_memset16
[09:21:32] [PASSED] test_memset32
[09:21:32] [PASSED] test_memset64
[09:21:32] [PASSED] test_strchr
[09:21:32] [PASSED] test_strnchr
[09:21:32] [PASSED] test_strspn
[09:21:32] ===================== [PASSED] string ======================
[09:21:32] ============================================================
[09:21:32] Testing complete. Ran 6 tests: passed: 6
[09:21:32] Elapsed time: 11.545s total, 0.001s configuring, 11.327s building, 0.183s running


> ...
> 
> >         if (i < 256)
> > -               return (i << 24) | (j << 16) | k | 0x8000;
> > -       return 0;
> > +               KUNIT_EXPECT_EQ(test, 0, (i << 24) | (j << 16) | k | 0x8000);
> 
> First of all, this special value encodes the problematic patterns, so
> you missed proper messaging.

Yeah, I see now this isn't a test but rather an encoded report. Since
the failures are caught earlier, I can improve those messages instead of
doing an encoded version.

> Second, the returned value has a constant, how do you expect 0 to be
> equal to something (guaranteed not to be 0)?
> 
> This needs a good rethink of what you should do in the KUnit approach.
> 
> ...
> 
> > +               KUNIT_EXPECT_EQ(test, 0, (i << 24) | (j << 16) | k | 0x8000);
> 
> Ditto.
> 
> ...
> 
> > +               KUNIT_EXPECT_EQ(test, 0, (i << 24) | (j << 16) | k | 0x8000);
> 
> Ditto.
> 
> ...
> 
> >         for (i = 0; i < strlen(test_string) + 1; i++) {
> >                 result = strchr(test_string, test_string[i]);
> > -               if (result - test_string != i)
> > -                       return i + 'a';
> > +               KUNIT_ASSERT_EQ(test, result - test_string, i);
> 
> In a similar way, all returned values are *special*, you really need
> to think about them before converting to a simple (and sometimes
> wrong) checks)

This encoding is trying to report "i", so I've adjusted the error
reporting in v3.

> I dunno if KUnit has a fault ejection simulation. It should, in order
> to be sure that test cases are fine when they fail.

Yeah, bumping offsets and such produce expected failures.

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/2] string: Convert selftest to KUnit
  2024-03-01 17:25     ` Kees Cook
@ 2024-03-01 17:29       ` Andy Shevchenko
  0 siblings, 0 replies; 9+ messages in thread
From: Andy Shevchenko @ 2024-03-01 17:29 UTC (permalink / raw
  To: Kees Cook; +Cc: linux-hardening, linux-kernel

On Fri, Mar 01, 2024 at 09:25:07AM -0800, Kees Cook wrote:
> On Fri, Mar 01, 2024 at 01:09:27PM +0200, Andy Shevchenko wrote:
> > On Fri, Mar 1, 2024 at 2:26 AM Kees Cook <keescook@chromium.org> wrote:
> > >
> > > Convert test_string.c to KUnit so it can be easily run with everything
> > > else.
> > 
> > Have you run it?
> 
> Yes:

Of course I new the answer :-)

The problem as I described is the (absence of) fault injection in KUnit itself.
When tests are passed the picture is nice, when they are not, the reports become
a disaster (if this is applied).

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/2] string: Convert helpers selftest to KUnit
  2024-03-01 11:20   ` Andy Shevchenko
@ 2024-03-01 20:29     ` Kees Cook
  0 siblings, 0 replies; 9+ messages in thread
From: Kees Cook @ 2024-03-01 20:29 UTC (permalink / raw
  To: Andy Shevchenko
  Cc: Andy Shevchenko, Kent Overstreet, linux-hardening, linux-kernel

On Fri, Mar 01, 2024 at 01:20:41PM +0200, Andy Shevchenko wrote:
> On Fri, Mar 1, 2024 at 2:26 AM Kees Cook <keescook@chromium.org> wrote:
> >
> > Convert test-string_helpers.c to KUnit so it can be easily run with
> > everything else.
> 
> ...
> 
> > -#include <linux/array_size.h>
> >  #include <linux/init.h>
> > +#include <kunit/test.h>
> 
> I know the order is broken here, but don't make it worse, please. And
> stick with one schema where to put kunit/test.h always before
> everything else and somewhere else (like always after linux/*).

Fixed.

> 
> > +#include <linux/array_size.h>
> >  #include <linux/kernel.h>
> >  #include <linux/slab.h>
> >  #include <linux/module.h>
> 
> ...
> 
> > +static void test_string_check_buf(struct kunit *test,
> > +                                 const char *name, unsigned int flags,
> > +                                 char *in, size_t p,
> > +                                 char *out_real, size_t q_real,
> > +                                 char *out_test, size_t q_test)
> >  {
> > -       if (q_real == q_test && !memcmp(out_test, out_real, q_test))
> > -               return true;
> > +       int result;
> > +
> > +       KUNIT_EXPECT_EQ(test, q_real, q_test);
> 
> This needs a message.
> 
> > +       result = memcmp(out_test, out_real, q_test);
> 
> > +       KUNIT_EXPECT_EQ(test, 0, result);
> 
> Why do we need this assertion? We have a dump below to show what's wrong.

I've improved this all around with ...STREQ and ...MEMEQ calls, and
added _MSG versions where needed to retain the prior reported test
context.

> ...
> 
> > +#define test_string_get_size_one(size, blk_size, exp_result10, exp_result2)      \
> > +       do {                                                                     \
> > +               BUILD_BUG_ON(sizeof(exp_result10) >= string_get_size_maxbuf);    \
> > +               BUILD_BUG_ON(sizeof(exp_result2) >= string_get_size_maxbuf);     \
> 
> No analogous assertions in KUnit?

It's designed for runtime testing. This is fine as-is for compile-time
asserts.

Thanks for the reviews!

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-03-01 20:29 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-01  0:26 [PATCH v2 0/2] string: Convert selftests to KUnit Kees Cook
2024-03-01  0:26 ` [PATCH v2 1/2] string: Convert selftest " Kees Cook
2024-03-01 11:09   ` Andy Shevchenko
2024-03-01 17:25     ` Kees Cook
2024-03-01 17:29       ` Andy Shevchenko
2024-03-01  0:26 ` [PATCH v2 2/2] string: Convert helpers " Kees Cook
2024-03-01 11:20   ` Andy Shevchenko
2024-03-01 20:29     ` Kees Cook
2024-03-01 11:22 ` [PATCH v2 0/2] string: Convert selftests " Andy Shevchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).