[PATCH v1] test_sysctl: unregister tables before freeing bitmap

From: Yibo Tan

Date: Sat Sep 19 2026 - 14:51:44 EST


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: Codex:GPT-5
Signed-off-by: Yibo Tan <lhfff@xxxxxxxxxx>
---
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 909cfcf76dbfc..dd795979558a2 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);

base-commit: 40288c9206c17eb66a603262e06a58d300d0f279
--
2.39.5