aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
authorLinus Torvalds <torvalds@linux-foundation.org>2026-05-26 13:37:26 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-05-26 13:37:26 -0700
commite909cedf6800ef493063f18a089f3632817a8c2d (patch)
treed1ff437b168fefda1e63465ef8e1b4a14074250d /lib
parentd60ec36cab338dfe2ae40d73e9c8d6c4af70d2b8 (diff)
parentfb6988b83b4cafe8db63999c1ddff1b7c66d2ff5 (diff)
downloadlinux-next-history-e909cedf6800ef493063f18a089f3632817a8c2d.tar.gz
Merge tag 'linux_kselftest-kunit-fixes-7.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
Pull kunit fix from Shuah Khan: "Fix a use-after-free in kunit debugfs when using kunit.filter when the executor frees dynamically allocated resources after running boot-time tests. This resulted in fatal hardware exception due to invalidation of capability flags on the reclaimed memory on some architectures such as CHERI RISC-V that support the feature, and silent memory corruption on others. The fix for this couples the lifetime of the filtered suite memory allocation to the lifetime of the kunit subsystem and its associated VFS nodes. Ownership of the boot-time suite_set is now transferred to a global tracker ('kunit_boot_suites'), and the memory is cleanly released in kunit_exit() during module teardown" * tag 'linux_kselftest-kunit-fixes-7.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: kunit: fix use-after-free in debugfs when using kunit.filter
Diffstat (limited to 'lib')
-rw-r--r--lib/kunit/executor.c19
-rw-r--r--lib/kunit/test.c1
2 files changed, 17 insertions, 3 deletions
diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c
index 1fef217de11db..b0f8a41d61d36 100644
--- a/lib/kunit/executor.c
+++ b/lib/kunit/executor.c
@@ -15,6 +15,16 @@ extern struct kunit_suite * const __kunit_suites_end[];
extern struct kunit_suite * const __kunit_init_suites_start[];
extern struct kunit_suite * const __kunit_init_suites_end[];
+static struct kunit_suite_set kunit_boot_suites;
+
+void kunit_free_boot_suites(void)
+{
+ if (kunit_boot_suites.start) {
+ kunit_free_suite_set(kunit_boot_suites);
+ kunit_boot_suites = (struct kunit_suite_set){ NULL, NULL };
+ }
+}
+
static char *action_param;
module_param_named(action, action_param, charp, 0400);
@@ -411,9 +421,12 @@ int kunit_run_all_tests(void)
pr_err("kunit executor: unknown action '%s'\n", action_param);
free_out:
- if (filter_glob_param || filter_param)
- kunit_free_suite_set(suite_set);
- else if (init_num_suites > 0)
+ if (filter_glob_param || filter_param) {
+ if (err)
+ kunit_free_suite_set(suite_set);
+ else
+ kunit_boot_suites = suite_set;
+ } else if (init_num_suites > 0)
/* Don't use kunit_free_suite_set because suites aren't individually allocated */
kfree(suite_set.start);
diff --git a/lib/kunit/test.c b/lib/kunit/test.c
index 41e1c89799b6a..99773e000e1b7 100644
--- a/lib/kunit/test.c
+++ b/lib/kunit/test.c
@@ -1075,6 +1075,7 @@ static void __exit kunit_exit(void)
kunit_bus_shutdown();
kunit_debugfs_cleanup();
+ kunit_free_boot_suites();
}
module_exit(kunit_exit);