mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
objtool/klp: Fix relocations for EXPORT_SYMBOL_FOR_MODULES() symbols
EXPORT_SYMBOL_FOR_MODULES() puts a symbol in a "module:<names>"
namespace, which the module loader grants access to by matching the
importing module's name against that list.
klp_reloc_needed() only creates a klp reloc for module-owned exports; a
vmlinux export gets a normal reloc. For a vmlinux symbol exported with
EXPORT_SYMBOL_FOR_MODULES(), using a normal reloc results in a modpost
failure in klp-build:
ERROR: modpost: module livepatch-foo uses symbol mpol_shared_policy_lookup from namespace module:kvm, but does not import it.
And the modpost error is correct: even with that error removed, the
patch module would fail to load:
livepatch_foo: module uses symbol (mpol_shared_policy_lookup) from namespace module:kvm, but does not import it.
livepatch_foo: Unknown symbol mpol_shared_policy_lookup (err -22)
Treat it like an unexported symbol by using a klp reloc.
Note this only affects "module:" namespaces. Ordinary namespaced
exports continue to work with normal relocs thanks to copy_import_ns(),
which propagates the patched object's import_ns tags to the patch
module.
Fixes: dd590d4d57 ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Reported-by: Joe Lawrence <joe.lawrence@redhat.com>
Link: https://lore.kernel.org/6a6608f4-0a05-4d75-8b7f-edddfac9c5d4@redhat.com
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
Acked-by: Song Liu <song@kernel.org>
Link: https://patch.msgid.link/fe5a00818e06ec613344d41d5944de054fcd8832.1786138493.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
This commit is contained in:
parent
72d76d0c18
commit
4cd3cfb8b5
|
|
@ -30,7 +30,9 @@ struct elfs {
|
|||
|
||||
struct export {
|
||||
struct hlist_node hash;
|
||||
char *mod, *sym;
|
||||
char *mod;
|
||||
char *sym;
|
||||
bool mod_ns;
|
||||
};
|
||||
|
||||
bool debug, debug_correlate, debug_clone;
|
||||
|
|
@ -135,7 +137,7 @@ static int read_exports(void)
|
|||
}
|
||||
|
||||
while (fgets(line, 1024, file)) {
|
||||
char *sym, *mod, *type;
|
||||
char *sym, *mod, *type, *namespace;
|
||||
struct export *export;
|
||||
|
||||
sym = strchr(line, '\t');
|
||||
|
|
@ -162,6 +164,14 @@ static int read_exports(void)
|
|||
|
||||
*type++ = '\0';
|
||||
|
||||
namespace = strchr(type, '\t');
|
||||
if (!namespace) {
|
||||
ERROR("malformed Module.symvers (namespace) at line %d", line_num);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*namespace++ = '\0';
|
||||
|
||||
if (*sym == '\0' || *mod == '\0') {
|
||||
ERROR("malformed Module.symvers at line %d", line_num);
|
||||
return -1;
|
||||
|
|
@ -188,6 +198,9 @@ static int read_exports(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* EXPORT_SYMBOL_FOR_MODULES() */
|
||||
export->mod_ns = strstarts(namespace, "module:");
|
||||
|
||||
hash_add(exports, &export->hash, str_hash(sym));
|
||||
}
|
||||
|
||||
|
|
@ -1175,11 +1188,16 @@ static bool klp_reloc_needed(struct reloc *patched_reloc)
|
|||
* clusterfunk that is late module patching, the patch module is
|
||||
* allowed to be loaded before any modules it depends on.
|
||||
*
|
||||
* If exported by vmlinux, a normal reloc will do.
|
||||
* If exported by vmlinux to all modules, a normal reloc will do.
|
||||
*/
|
||||
export = find_export(patched_sym);
|
||||
if (export)
|
||||
return strcmp(export->mod, "vmlinux");
|
||||
if (export) {
|
||||
if (strcmp(export->mod, "vmlinux"))
|
||||
return true;
|
||||
|
||||
/* EXPORT_SYMBOL_FOR_MODULES() gets a klp reloc */
|
||||
return export->mod_ns;
|
||||
}
|
||||
|
||||
if (!patched_sym->twin) {
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user