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: 2ea622b887 ("tools/testing/selftests/sysctl/sysctl.sh: add proc_do_large_bitmap() test case")
Assisted-by: LLM
Signed-off-by: Yibo Tan <lhfff@tju.edu.cn>
Signed-off-by: Joel Granados <joel.granados@kernel.org>
This commit is contained in:
Yibo Tan 2026-09-20 02:51:10 +08:00 committed by Joel Granados
parent ccb5bf46e3
commit 238dfe02fb

View File

@ -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);