summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Poimboeuf <jpoimboe@kernel.org>2026-08-07 14:37:51 -0700
committerJosh Poimboeuf <jpoimboe@kernel.org>2026-08-11 16:10:51 -0700
commit86a697572c6271083694025eefa8de518eeef623 (patch)
tree1af9f149c7f11206c259611ff0c39f24bd1e4503
parent07f14d6af9d7791fdc2b44a3dd0693e42c71d2b8 (diff)
objtool/klp: Don't match local symbols against exports
While cloning a reloc, klp diff calls find_export() to determine whether the referenced symbol is exported. That decides whether the reference needs a klp reloc, which object the klp symbol belongs to, and whether the symbol's data needs to be copied into the patch module. But find_export() matches purely on symbol name, so a static function or variable which happens to share its name with an export is mistaken for a reference to that export: - klp_reloc_needed() creates a klp reloc pointing at the exporting module's symbol rather than the local one. For a vmlinux export it skips the klp reloc altogether, leaving a normal reloc which the module loader resolves to the vmlinux symbol. - clone_reloc() treats the symbol as external and clones it without its data, leaving a dangling reference. - validate_special_section_klp_reloc() attributes a static branch or call key to the wrong module, and for a vmlinux export skips the unsupported-key check entirely. Exports are always global, so ignore local symbols in find_export(). Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files") Acked-by: Song Liu <song@kernel.org> Acked-by: Joe Lawrence <joe.lawrence@redhat.com> Link: https://patch.msgid.link/dafc7c017d1f62e2190a20dc84a52fbfc4c70210.1786138493.git.jpoimboe@kernel.org Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
-rw-r--r--tools/objtool/klp-diff.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index e266a54b059d..a7cdba08b1de 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -1102,6 +1102,9 @@ static struct export *find_export(struct symbol *sym)
{
struct export *export;
+ if (is_local_sym(sym))
+ return NULL;
+
hash_for_each_possible(exports, export, hash, str_hash(sym->name)) {
if (!strcmp(export->sym, sym->name))
return export;