lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20250710155139.322955-1-pmladek@suse.com>
Date: Thu, 10 Jul 2025 17:51:39 +0200
From: Petr Mladek <pmladek@...e.com>
To: Thomas Weißschuh <thomas.weissschuh@...utronix.de>,
	John Ogness <john.ogness@...utronix.de>,
	Dan Carpenter <dan.carpenter@...aro.org>
Cc: Steven Rostedt <rostedt@...dmis.org>,
	Sergey Senozhatsky <senozhatsky@...omium.org>,
	Kees Cook <kees@...nel.org>,
	"Gustavo A . R . Silva" <gustavoars@...nel.org>,
	David Gow <davidgow@...gle.com>,
	Arnd Bergmann <arnd@...nel.org>,
	Arnd Bergmann <arnd@...db.de>,
	linux-kernel@...r.kernel.org,
	linux-hardening@...r.kernel.org,
	Petr Mladek <pmladek@...e.com>
Subject: [PATCH v3] printk: kunit: support offstack cpumask

From: Arnd Bergmann <arnd@...db.de>

For large values of CONFIG_NR_CPUS, the newly added kunit test fails
to build:

kernel/printk/printk_ringbuffer_kunit_test.c: In function 'test_readerwriter':
kernel/printk/printk_ringbuffer_kunit_test.c:279:1: error: the frame size of 1432 bytes is larger than 1280 bytes [-Werror=frame-larger-than=]

Change this to use cpumask_var_t and allocate it dynamically when
CONFIG_CPUMASK_OFFSTACK is set.

alloc_cpumask_var() and free_cpumask_var() are not called when
CONFIG_CPUMASK_OFFSTACK is not set. It would require an explicit cast
in the clean up action, leaking the stack address to the kthread doing
the clean up, or another workaround. And both function do nothing
do nothing in this case, anyway. It looks likes the least evil solution.

Fixes: 5ea2bcdfbf46 ("printk: ringbuffer: Add KUnit test")
Signed-off-by: Arnd Bergmann <arnd@...db.de>
[pmladek@...e.com: Correctly handle allocation failures and freeing using KUnit test API.]
Reviewed-by: Thomas Weißschuh <thomas.weissschuh@...utronix.de>
Signed-off-by: Petr Mladek <pmladek@...e.com>
---
This is actually 3rd version of the patch.

Changes against [v2]:

  + Fix compilation without CONFIG_CPUMASK_OFFSTACK

Changes against [v1]

  + Use KUnit API for handling allocation failure and freeing.

[v2] https://lore.kernel.org/r/20250702095157.110916-3-pmladek@suse.com
[v1] https://lore.kernel.org/r/20250620192554.2234184-1-arnd@kernel.org

The patch applies on the top of printk/linux.git,
branch rework/ringbuffer-kunit-test.

 kernel/printk/printk_ringbuffer_kunit_test.c | 35 ++++++++++++++++----
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/kernel/printk/printk_ringbuffer_kunit_test.c b/kernel/printk/printk_ringbuffer_kunit_test.c
index e67e1815f4c8..21000d7d7a32 100644
--- a/kernel/printk/printk_ringbuffer_kunit_test.c
+++ b/kernel/printk/printk_ringbuffer_kunit_test.c
@@ -223,6 +223,27 @@ static int prbtest_reader(struct prbtest_data *test_data, unsigned long timeout_
 	return 0;
 }
 
+/*
+ * A cast would be needed for the clean up action when the cpumask was on stack.
+ * Also it would leak the stack address to the cleanup thread.
+ * And alloc_cpu_mask() and free_cpumask_var() would do nothing anyway.
+ */
+#ifdef CONFIG_CPUMASK_OFFSTACK
+KUNIT_DEFINE_ACTION_WRAPPER(prbtest_cpumask_cleanup, free_cpumask_var, cpumask_var_t);
+
+static void prbtest_alloc_cpumask(struct kunit *test, cpumask_var_t *mask)
+{
+	int err;
+
+	KUNIT_ASSERT_TRUE(test, alloc_cpumask_var(mask, GFP_KERNEL));
+	err = kunit_add_action_or_reset(test, prbtest_cpumask_cleanup, *mask);
+	KUNIT_ASSERT_EQ(test, err, 0);
+}
+#else
+static inline
+void prbtest_alloc_cpumask(struct kunit *test, cpumask_var_t *mask) {}
+#endif
+
 KUNIT_DEFINE_ACTION_WRAPPER(prbtest_kthread_cleanup, kthread_stop, struct task_struct *);
 
 static void prbtest_add_kthread_cleanup(struct kunit *test, struct task_struct *kthread)
@@ -247,9 +268,11 @@ static void test_readerwriter(struct kunit *test)
 	struct prbtest_thread_data *thread_data;
 	struct prbtest_data *test_data;
 	struct task_struct *thread;
-	cpumask_t test_cpus;
+	cpumask_var_t test_cpus;
 	int cpu, reader_cpu;
 
+	prbtest_alloc_cpumask(test, &test_cpus);
+
 	cpus_read_lock();
 	/*
 	 * Failure of KUNIT_ASSERT() kills the current task
@@ -257,15 +280,15 @@ static void test_readerwriter(struct kunit *test)
 	 * Instead use a snapshot of the online CPUs.
 	 * If they change during test execution it is unfortunate but not a grave error.
 	 */
-	cpumask_copy(&test_cpus, cpu_online_mask);
+	cpumask_copy(test_cpus, cpu_online_mask);
 	cpus_read_unlock();
 
 	/* One CPU is for the reader, all others are writers */
-	reader_cpu = cpumask_first(&test_cpus);
-	if (cpumask_weight(&test_cpus) == 1)
+	reader_cpu = cpumask_first(test_cpus);
+	if (cpumask_weight(test_cpus) == 1)
 		kunit_warn(test, "more than one CPU is recommended");
 	else
-		cpumask_clear_cpu(reader_cpu, &test_cpus);
+		cpumask_clear_cpu(reader_cpu, test_cpus);
 
 	/* KUnit test can get restarted more times. */
 	prbtest_prb_reinit(&test_rb);
@@ -278,7 +301,7 @@ static void test_readerwriter(struct kunit *test)
 
 	kunit_info(test, "running for %lu ms\n", runtime_ms);
 
-	for_each_cpu(cpu, &test_cpus) {
+	for_each_cpu(cpu, test_cpus) {
 		thread_data = kunit_kmalloc(test, sizeof(*thread_data), GFP_KERNEL);
 		KUNIT_ASSERT_NOT_NULL(test, thread_data);
 		thread_data->test_data = test_data;
-- 
2.50.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ