[PATCH v2] lkdtm/core: fix resource leaks on module init error path
From: Jiangshan Yi
Date: Thu Jul 30 2026 - 12:23:15 EST
When lkdtm_register_cpoint() fails, the out_err path only removes
debugfs but leaks the kmem_caches from lkdtm_heap_init() /
lkdtm_usercopy_init() and the lkdtm_kernel_info string, because the
kernel never calls module_exit() on init failure.
Add the missing cleanup calls to out_err. Drop __exit from
lkdtm_heap_exit() and lkdtm_usercopy_exit() to avoid section mismatch:
these functions are now called from __init context, and .exit.text is
discarded for built-in builds.
Fixes: 039a1c42058d ("lkdtm: Relocate code to subdirectory")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Jiangshan Yi <yijiangshan@xxxxxxxxxx>
---
Changes in v2:
- Drop __exit annotation to fix section mismatch when built-in.
drivers/misc/lkdtm/core.c | 3 +++
drivers/misc/lkdtm/heap.c | 2 +-
drivers/misc/lkdtm/lkdtm.h | 4 ++--
drivers/misc/lkdtm/usercopy.c | 2 +-
4 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c
index ededa32d6744..1e3a5e45e3c2 100644
--- a/drivers/misc/lkdtm/core.c
+++ b/drivers/misc/lkdtm/core.c
@@ -468,6 +468,9 @@ static int __init lkdtm_module_init(void)
out_err:
debugfs_remove_recursive(lkdtm_debugfs_root);
+ lkdtm_heap_exit();
+ lkdtm_usercopy_exit();
+ kfree(lkdtm_kernel_info);
return ret;
}
diff --git a/drivers/misc/lkdtm/heap.c b/drivers/misc/lkdtm/heap.c
index 9e358d15f4fb..d01e3a3e3e3e 100644
--- a/drivers/misc/lkdtm/heap.c
+++ b/drivers/misc/lkdtm/heap.c
@@ -363,7 +363,7 @@ void __init lkdtm_heap_init(void)
b_cache = kmem_cache_create("lkdtm-heap-b", 64, 0, SLAB_NO_MERGE, NULL);
}
-void __exit lkdtm_heap_exit(void)
+void lkdtm_heap_exit(void)
{
kmem_cache_destroy(double_free_cache);
kmem_cache_destroy(a_cache);
diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h
index 3a57c4e5e978..e3a3e3c3e3e3 100644
--- a/drivers/misc/lkdtm/lkdtm.h
+++ b/drivers/misc/lkdtm/lkdtm.h
@@ -89,9 +89,9 @@ extern struct crashtype_category powerpc_crashtypes;
/* Each category's init/exit routines. */
void __init lkdtm_bugs_init(int *recur_param);
void __init lkdtm_heap_init(void);
-void __exit lkdtm_heap_exit(void);
+void lkdtm_heap_exit(void);
void __init lkdtm_perms_init(void);
void __init lkdtm_usercopy_init(void);
-void __exit lkdtm_usercopy_exit(void);
+void lkdtm_usercopy_exit(void);
/* Special declaration for function-in-rodata. */
void lkdtm_rodata_do_nothing(void);
diff --git a/drivers/misc/lkdtm/usercopy.c b/drivers/misc/lkdtm/usercopy.c
index 2f3c5034a3e3..e3a3e3e3e3e3 100644
--- a/drivers/misc/lkdtm/usercopy.c
+++ b/drivers/misc/lkdtm/usercopy.c
@@ -433,7 +433,7 @@ void __init lkdtm_usercopy_init(void)
NULL);
}
-void __exit lkdtm_usercopy_exit(void)
+void lkdtm_usercopy_exit(void)
{
kmem_cache_destroy(whitelist_cache);
}
--
2.25.1