summaryrefslogtreecommitdiff
path: root/kernel/module
diff options
context:
space:
mode:
authorStanislaw Gruszka <stf_xl@wp.pl>2026-03-27 12:00:04 +0100
committerPetr Pavlu <petr.pavlu@suse.com>2026-07-10 14:25:09 +0200
commit5eef17fedaa5aa1d7a504b49c53ad2e121698f17 (patch)
tree665a0b64bb9b829557b11e7385a1938897a61416 /kernel/module
parent8cdeaa50eae8dad34885515f62559ee83e7e8dda (diff)
downloadlinux-next-5eef17fedaa5aa1d7a504b49c53ad2e121698f17.tar.gz
linux-next-5eef17fedaa5aa1d7a504b49c53ad2e121698f17.zip
module/kallsyms: fix nextval for data symbol lookup
The symbol lookup code assumes the queried address resides in either MOD_TEXT or MOD_INIT_TEXT. This breaks for addresses in other module memory regions (e.g. rodata or data), resulting in incorrect upper bounds and wrong symbol size. Select the module memory region the address belongs to instead of hardcoding text sections. Also initialize the lower bound to the start of that region, as searching from address 0 is unnecessary. Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl> Reviewed-by: Petr Pavlu <petr.pavlu@suse.com> Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
Diffstat (limited to 'kernel/module')
-rw-r--r--kernel/module/kallsyms.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c
index 0fc11e45df9b..f23126d804b2 100644
--- a/kernel/module/kallsyms.c
+++ b/kernel/module/kallsyms.c
@@ -258,17 +258,25 @@ static const char *find_kallsyms_symbol(struct module *mod,
unsigned int i, best = 0;
unsigned long nextval, bestval;
struct mod_kallsyms *kallsyms = rcu_dereference(mod->kallsyms);
- struct module_memory *mod_mem;
+ struct module_memory *mod_mem = NULL;
- /* At worse, next value is at end of module */
- if (within_module_init(addr, mod))
- mod_mem = &mod->mem[MOD_INIT_TEXT];
- else
- mod_mem = &mod->mem[MOD_TEXT];
+ for_each_mod_mem_type(type) {
+#ifndef CONFIG_KALLSYMS_ALL
+ if (!mod_mem_type_is_text(type))
+ continue;
+#endif
+ if (within_module_mem_type(addr, mod, type)) {
+ mod_mem = &mod->mem[type];
+ break;
+ }
+ }
- nextval = (unsigned long)mod_mem->base + mod_mem->size;
+ if (!mod_mem)
+ return NULL;
- bestval = kallsyms_symbol_value(&kallsyms->symtab[best]);
+ /* Initialize bounds within memory region the address belongs to. */
+ nextval = (unsigned long)mod_mem->base + mod_mem->size;
+ bestval = (unsigned long)mod_mem->base - 1;
/*
* Scan for closest preceding symbol, and next symbol. (ELF