Re: [PATCH 2/2] lib/tests: Add KUnit test for struct stack_trace __counted_by_ptr attribute

Kuan-Wei Chiu <[email protected]>
Newsgroups org.kernel.vger.linux-hardening,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest
Message-ID <[email protected]>
Hi Bill,

On Sun, Aug 23, 2026 at 12:35:33PM +0000, Bill Wendling wrote:
> Add a custom KUnit test suite 'stacktrace_counted_by' to verify that the
> __counted_by_ptr annotation on the 'entries' field of 'struct stack_trace'
> behaves correctly.
> 
> The test verifies that 'max_entries' correctly limits and validates access
> to 'entries' when CONFIG_ARCH_STACKWALK is not defined. If it is defined,
> the test is cleanly skipped at runtime to prevent compile-time or runtime
> failures due to 'struct stack_trace' being undefined on modern
> architectures.
> 
> Assisted-by: Gemini Next
> Signed-off-by: Bill Wendling <[email protected]>
> ---
> Cc: Kees Cook <[email protected]>
> Cc: "Gustavo A. R. Silva" <[email protected]>
> Cc: Andrew Morton <[email protected]>
> Cc: Brendan Higgins <[email protected]>
> Cc: David Gow <[email protected]>
> Cc: Rae Moar <[email protected]>
> Cc: Ryota Sakamoto <[email protected]>
> Cc: Kuan-Wei Chiu <[email protected]>
> Cc: Pasha Tatashin <[email protected]>
> Cc: Dmitry Antipov <[email protected]>
> Cc: Petr Mladek <[email protected]>
> Cc: Kir Chou <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
>  lib/Kconfig.debug            | 10 +++++++
>  lib/kunit/.kunitconfig       |  1 +
>  lib/tests/Makefile           |  1 +
>  lib/tests/stacktrace_kunit.c | 51 ++++++++++++++++++++++++++++++++++++
>  4 files changed, 63 insertions(+)
>  create mode 100644 lib/tests/stacktrace_kunit.c
> 
> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> index e97bdf3a42a8..51a6ac1a2461 100644
> --- a/lib/Kconfig.debug
> +++ b/lib/Kconfig.debug
> @@ -2716,6 +2716,16 @@ config BITOPS_KUNIT
>  
>  	  If unsure, say N.
>  
> +config STACKTRACE_KUNIT_TEST
> +	tristate "KUnit test for stacktrace counted_by attribute" if !KUNIT_ALL_TESTS
> +	depends on KUNIT
> +	default KUNIT_ALL_TESTS
> +	help
> +	  This option enables the KUnit test for verifying the __counted_by_ptr
> +	  attribute on struct stack_trace.
> +
> +	  If unsure, say N.
> +
>  config BITFIELD_KUNIT
>  	tristate "KUnit test bitfield functions at runtime" if !KUNIT_ALL_TESTS
>  	depends on KUNIT
> diff --git a/lib/kunit/.kunitconfig b/lib/kunit/.kunitconfig
> index 9235b7d42d38..b3761b41459e 100644
> --- a/lib/kunit/.kunitconfig
> +++ b/lib/kunit/.kunitconfig
> @@ -1,3 +1,4 @@
>  CONFIG_KUNIT=y
>  CONFIG_KUNIT_TEST=y
>  CONFIG_KUNIT_EXAMPLE_TEST=y
> +CONFIG_STACKTRACE_KUNIT_TEST=y
> diff --git a/lib/tests/Makefile b/lib/tests/Makefile
> index 4ead57602eac..40875e729fc8 100644
> --- a/lib/tests/Makefile
> +++ b/lib/tests/Makefile
> @@ -6,6 +6,7 @@
>  CFLAGS_bitfield_kunit.o := $(DISABLE_STRUCTLEAK_PLUGIN)
>  obj-$(CONFIG_BASE64_KUNIT) += base64_kunit.o
>  obj-$(CONFIG_BITOPS_KUNIT) += bitops_kunit.o
> +obj-$(CONFIG_STACKTRACE_KUNIT_TEST) += stacktrace_kunit.o
>  obj-$(CONFIG_BITFIELD_KUNIT) += bitfield_kunit.o
>  obj-$(CONFIG_BITS_TEST) += test_bits.o
>  obj-$(CONFIG_SHDI3_KUNIT_TEST) += shdi3_kunit.o
> diff --git a/lib/tests/stacktrace_kunit.c b/lib/tests/stacktrace_kunit.c
> new file mode 100644
> index 000000000000..7ec48edf84fe
> --- /dev/null
> +++ b/lib/tests/stacktrace_kunit.c
> @@ -0,0 +1,51 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * KUnit test for struct stack_trace counted_by attribute.
> + */
> +
> +#include <kunit/test.h>
> +#include <linux/stacktrace.h>
> +
> +#ifndef CONFIG_ARCH_STACKWALK
> +static void test_stack_trace_counted_by(struct kunit *test)
> +{
> +	unsigned long entries_buf[4];
> +	struct stack_trace trace = {
> +		.entries = entries_buf,
> +		.max_entries = 4,
> +	};
> +
> +	KUNIT_EXPECT_EQ(test, trace.max_entries, 4U);
> +	KUNIT_EXPECT_PTR_EQ(test, trace.entries, (unsigned long *)entries_buf);
> +
> +	/* Write to the allocated elements to verify access */
> +	trace.entries[0] = 0xdeadbeef;
> +	trace.entries[1] = 0xbeefcafe;
> +	trace.entries[2] = 0xcafebabe;
> +	trace.entries[3] = 0x12345678;

This only does in bounds array writes.
To test __counted_by_ptr, I thought we were supposed to intentionally
trigger an out of bounds access and see if it actually catches the
error?

Regards,
Kuan-Wei

> +
> +	KUNIT_EXPECT_EQ(test, trace.entries[0], 0xdeadbeefUL);
> +	KUNIT_EXPECT_EQ(test, trace.entries[1], 0xbeefcafeUL);
> +	KUNIT_EXPECT_EQ(test, trace.entries[2], 0xcafebabeUL);
> +	KUNIT_EXPECT_EQ(test, trace.entries[3], 0x12345678UL);
> +}
> +#else
> +static void test_stack_trace_counted_by(struct kunit *test)
> +{
> +	kunit_skip(test, "CONFIG_ARCH_STACKWALK is enabled, struct stack_trace is not defined");
> +}
> +#endif
> +
> +static struct kunit_case stacktrace_test_cases[] = {
> +	KUNIT_CASE(test_stack_trace_counted_by),
> +	{}
> +};
> +
> +static struct kunit_suite stacktrace_test_suite = {
> +	.name = "stacktrace_counted_by",
> +	.test_cases = stacktrace_test_cases,
> +};
> +
> +kunit_test_suite(stacktrace_test_suite);
> +
> +MODULE_LICENSE("GPL");
> -- 
> 2.55.0.860.g4b6b3295ed-goog
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.