lib/test_sysctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
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@tju.edu.cn>
---
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
On Sun, Sep 20, 2026 at 02:51:10AM +0800, Yibo Tan wrote:
> 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
I'll change this to Assisted-by: LLM like it says in Documentation/process/coding-assistants.rst
> Signed-off-by: Yibo Tan <lhfff@tju.edu.cn>
> ---
> 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
I'll leave the Fixes tag but will add this to sysctl-next as opposed to
pushing it through as a fix for 7.3. Lets avoid making noise just for
the testing module.
Thx for the fix
Best
On Fri, Sep 25, 2026 at 11:03:31AM +0200, Joel Granados wrote:
> On Sun, Sep 20, 2026 at 02:51:10AM +0800, Yibo Tan wrote:
> > 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
>
> I'll change this to Assisted-by: LLM like it says in Documentation/process/coding-assistants.rst
I'll also update the commit message header to sysctl: from test_sysctl:
>
> > Signed-off-by: Yibo Tan <lhfff@tju.edu.cn>
> > ---
> > 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
>
> I'll leave the Fixes tag but will add this to sysctl-next as opposed to
> pushing it through as a fix for 7.3. Lets avoid making noise just for
> the testing module.
>
> Thx for the fix
>
> Best
>
© 2016 - 2026 Red Hat, Inc.