linux: compatible modules without kallsyms on KALLSYMS enabled kernel
linux/module.h: move kallsyms to the end of struct
This commit is contained in:
parent
f778584050
commit
a0f8ed1334
@ -0,0 +1,131 @@
|
||||
From e3b12676bb6b3c4fed08f2153749cfc7dd1c4c8b Mon Sep 17 00:00:00 2001
|
||||
From: jjm2473 <jjm2473@gmail.com>
|
||||
Date: Thu, 2 Jan 2025 18:39:43 +0800
|
||||
Subject: [PATCH] header: linux/module.h: move kallsyms to the end of struct
|
||||
|
||||
kernel: compatible modules without kallsyms on KALLSYMS enabled kernel
|
||||
|
||||
for better compatible
|
||||
---
|
||||
include/linux/module.h | 24 ++++++++++++------------
|
||||
kernel/module/main.c | 31 +++++++++++++++++++++++++++++++
|
||||
2 files changed, 43 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/include/linux/module.h b/include/linux/module.h
|
||||
index 06caf5a4a..66362f8c8 100644
|
||||
--- a/include/linux/module.h
|
||||
+++ b/include/linux/module.h
|
||||
@@ -474,18 +474,6 @@ struct module {
|
||||
struct bug_entry *bug_table;
|
||||
#endif
|
||||
|
||||
-#ifdef CONFIG_KALLSYMS
|
||||
- /* Protected by RCU and/or module_mutex: use rcu_dereference() */
|
||||
- struct mod_kallsyms __rcu *kallsyms;
|
||||
- struct mod_kallsyms core_kallsyms;
|
||||
-
|
||||
- /* Section attributes */
|
||||
- struct module_sect_attrs *sect_attrs;
|
||||
-
|
||||
- /* Notes attributes */
|
||||
- struct module_notes_attrs *notes_attrs;
|
||||
-#endif
|
||||
-
|
||||
/* The command line arguments (may be mangled). People like
|
||||
keeping pointers to this stuff */
|
||||
char *args;
|
||||
@@ -586,6 +574,18 @@ struct module {
|
||||
#ifdef CONFIG_DYNAMIC_DEBUG_CORE
|
||||
struct _ddebug_info dyndbg_info;
|
||||
#endif
|
||||
+
|
||||
+#ifdef CONFIG_KALLSYMS
|
||||
+ /* Protected by RCU and/or module_mutex: use rcu_dereference() */
|
||||
+ struct mod_kallsyms __rcu *kallsyms;
|
||||
+ struct mod_kallsyms core_kallsyms;
|
||||
+
|
||||
+ /* Section attributes */
|
||||
+ struct module_sect_attrs *sect_attrs;
|
||||
+
|
||||
+ /* Notes attributes */
|
||||
+ struct module_notes_attrs *notes_attrs;
|
||||
+#endif
|
||||
} ____cacheline_aligned __randomize_layout;
|
||||
#ifndef MODULE_ARCH_INIT
|
||||
#define MODULE_ARCH_INIT {}
|
||||
diff --git a/kernel/module/main.c b/kernel/module/main.c
|
||||
index 55cc7eaa2..5a88ef41e 100644
|
||||
--- a/kernel/module/main.c
|
||||
+++ b/kernel/module/main.c
|
||||
@@ -1550,6 +1550,16 @@ static void __layout_sections(struct module *mod, struct load_info *info, bool i
|
||||
if (WARN_ON_ONCE(type == MOD_INVALID))
|
||||
continue;
|
||||
|
||||
+#ifdef CONFIG_KALLSYMS
|
||||
+ if (i == info->index.mod && sizeof(struct module) > s->sh_size) {
|
||||
+ pr_warn("%s: module has no kallsyms\n",
|
||||
+ info->name);
|
||||
+ Elf_Shdr dummy;
|
||||
+ dummy.sh_addralign = s->sh_addralign;
|
||||
+ dummy.sh_size = sizeof(struct module);
|
||||
+ s->sh_entsize = module_get_offset_and_type(mod, type, &dummy, i);
|
||||
+ } else
|
||||
+#endif
|
||||
s->sh_entsize = module_get_offset_and_type(mod, type, s, i);
|
||||
pr_debug("\t%s\n", sname);
|
||||
}
|
||||
@@ -1870,11 +1880,19 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
|
||||
goto no_exec;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KALLSYMS
|
||||
+ if (shdr->sh_size > sizeof(struct module)) {
|
||||
+ pr_err("module %s: .gnu.linkonce.this_module section size must match the kernel's built struct module size at run time\n",
|
||||
+ info->name ?: "(missing .modinfo section or name field)");
|
||||
+ goto no_exec;
|
||||
+ }
|
||||
+#else
|
||||
if (shdr->sh_size != sizeof(struct module)) {
|
||||
pr_err("module %s: .gnu.linkonce.this_module section size must match the kernel's built struct module size at run time\n",
|
||||
info->name ?: "(missing .modinfo section or name field)");
|
||||
goto no_exec;
|
||||
}
|
||||
+#endif
|
||||
|
||||
info->index.mod = mod_idx;
|
||||
|
||||
@@ -2277,11 +2295,19 @@ static int move_module(struct module *mod, struct load_info *info)
|
||||
* end up copying over all modifications made to the
|
||||
* userspace copy of the entire struct module.
|
||||
*/
|
||||
+#ifdef CONFIG_KALLSYMS
|
||||
+ if (i == info->index.mod &&
|
||||
+ (WARN_ON_ONCE(shdr->sh_size > sizeof(struct module)))) {
|
||||
+ ret = -ENOEXEC;
|
||||
+ goto out_enomem;
|
||||
+ }
|
||||
+#else
|
||||
if (i == info->index.mod &&
|
||||
(WARN_ON_ONCE(shdr->sh_size != sizeof(struct module)))) {
|
||||
ret = -ENOEXEC;
|
||||
goto out_enomem;
|
||||
}
|
||||
+#endif
|
||||
memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size);
|
||||
}
|
||||
/*
|
||||
@@ -2291,6 +2317,11 @@ static int move_module(struct module *mod, struct load_info *info)
|
||||
* minted official memory area.
|
||||
*/
|
||||
shdr->sh_addr = (unsigned long)dest;
|
||||
+
|
||||
+#ifdef CONFIG_KALLSYMS
|
||||
+ if (i == info->index.mod && sizeof(struct module) > shdr->sh_size)
|
||||
+ shdr->sh_size = sizeof(struct module);
|
||||
+#endif
|
||||
pr_debug("\t0x%lx 0x%.8lx %s\n", (long)shdr->sh_addr,
|
||||
(long)shdr->sh_size, info->secstrings + shdr->sh_name);
|
||||
}
|
||||
--
|
||||
2.46.0
|
||||
|
||||
Loading…
Reference in New Issue
Block a user