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.

Cc: stable@vger.kernel.org
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>
This commit is contained in:
Stanislaw Gruszka 2026-03-27 12:00:04 +01:00 committed by Petr Pavlu
parent 8cdeaa50ea
commit 0e9f090a4e

View File

@ -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;
}
}
if (!mod_mem)
return NULL;
/* Initialize bounds within memory region the address belongs to. */
nextval = (unsigned long)mod_mem->base + mod_mem->size;
bestval = kallsyms_symbol_value(&kallsyms->symtab[best]);
bestval = (unsigned long)mod_mem->base - 1;
/*
* Scan for closest preceding symbol, and next symbol. (ELF