From 238dfe02fb0a9f72d7fd275d74ce80f13923ef31 Mon Sep 17 00:00:00 2001 From: Yibo Tan Date: Sun, 20 Sep 2026 02:51:10 +0800 Subject: [PATCH] sysctl: unregister tables before freeing bitmap The table registered for bitmap_0001 retains a pointer to test_data.bitmap_0001. unregister_sysctl_table() prevents new handlers from starting and waits for active handlers to finish. test_sysctl_exit() currently frees the bitmap before unregistering the table. A concurrent read during module removal can therefore enter proc_do_large_bitmap() while the bitmap is freed. KASAN reports a slab-use-after-free in _find_next_bit(). Unregister all tables before freeing the bitmap so the unregister rundown provides the required lifetime boundary. The unmodified module reproduced the use-after-free in three KASAN runs. With this change, three runs each completed 100 load, read and unload race rounds without a kernel diagnostic. Fixes: 2ea622b887e7 ("tools/testing/selftests/sysctl/sysctl.sh: add proc_do_large_bitmap() test case") Assisted-by: LLM Signed-off-by: Yibo Tan Signed-off-by: Joel Granados --- lib/test_sysctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/test_sysctl.c b/lib/test_sysctl.c index 909cfcf76dbf..dd795979558a 100644 --- a/lib/test_sysctl.c +++ b/lib/test_sysctl.c @@ -321,11 +321,11 @@ module_init(test_sysctl_init); static void __exit test_sysctl_exit(void) { - kfree(test_data.bitmap_0001); for (int i = 0; i < TEST_H_SIZE; i++) { if (ctl_headers[i]) unregister_sysctl_table(ctl_headers[i]); } + kfree(test_data.bitmap_0001); } module_exit(test_sysctl_exit);