mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-10 22:50:07 -04:00
When a module function references a vmlinux symbol which is exported with EXPORT_SYMBOL_FOR_MODULES(), a patch to that function needs to use a klp reloc. Currently, livepatch fails to load such a module: livepatch: invalid access to vmlinux symbol 'get_task_policy' from module-specific livepatch relocation section livepatch: failed to initialize patch 'livepatch_test' for module 'testmod' (-22) livepatch: patch 'livepatch_test' failed for module 'testmod', refusing to load module 'testmod' klp diff puts all klp relocs in __klp_relocs.<patched object>, so post-link names the section .klp.rela.<patched object>.<secname>, which the kernel rejects for vmlinux symbols. Commit07f14d6af9("objtool/klp: Fix cross-module klp relocation section naming") changed the meaning of objname in the klp rela section name to be where the referenced symbol is referenced rather than where it lives. That premise only holds for symbols in a module: the relocs get applied when the patched module gets patched, and the module dependency guarantees the referenced module is loaded by then. A vmlinux symbol needs the opposite. It's always resolvable, and it has to be applied when the patch module loads, before the module loader initializes the patch module's special sections, which may reference it. That's why livepatch rejects vmlinux symbols in module-specific sections. Use "vmlinux" as the section objname when the referenced symbol lives in vmlinux. This moves such klp relocs from .klp.rela.kvm..text to .klp.rela.vmlinux..text. Fixes:07f14d6af9("objtool/klp: Fix cross-module klp relocation section naming") Reported-by: Dylan Hatch <dylanbhatch@google.com> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Acked-by: Song Liu <song@kernel.org> Link: https://patch.msgid.link/f8e3b9fae109903a6aafb2a33310e4afdcebf58e.1786761327.git.jpoimboe@kernel.org Closes: https://lore.kernel.org/CADBMgpz7iWC0=t=_gE-tfvv0mTPq4kg0qQ2zgPH8DVPE6eQ9Kw@mail.gmail.com
64 lines
1.8 KiB
C
64 lines
1.8 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
#ifndef _OBJTOOL_KLP_H
|
|
#define _OBJTOOL_KLP_H
|
|
|
|
#define SHF_RELA_LIVEPATCH 0x00100000
|
|
#define SHN_LIVEPATCH 0xff20
|
|
|
|
/*
|
|
* .init.klp_objects and .init.klp_funcs are created by klp diff and used by the
|
|
* patch module init code to build the klp_patch, klp_object and klp_func
|
|
* structs needed by the livepatch API.
|
|
*/
|
|
#define KLP_OBJECTS_SEC ".init.klp_objects"
|
|
#define KLP_FUNCS_SEC ".init.klp_funcs"
|
|
|
|
/*
|
|
* __klp_relocs.<objname> are intermediate sections which are created by klp
|
|
* diff and converted into KLP symbols/relas by "objtool klp post-link". This
|
|
* is needed to work around the linker, which doesn't preserve SHN_LIVEPATCH or
|
|
* SHF_RELA_LIVEPATCH, nor does it support having two RELA sections for a
|
|
* single PROGBITS section.
|
|
*
|
|
* "objname" is the object whose loading gates the relocation: "vmlinux" for
|
|
* references to vmlinux symbols, otherwise the name of the module being
|
|
* patched. post-link uses it to name the resulting
|
|
* .klp.rela.objname.section_name sections.
|
|
*/
|
|
#define KLP_RELOCS_SEC "__klp_relocs"
|
|
#define KLP_STRINGS_SEC ".rodata.klp.str1.1"
|
|
|
|
#define KLP_TOMBSTONE_PREFIX ".klp.tombstone."
|
|
|
|
struct klp_reloc {
|
|
void *offset;
|
|
void *sym;
|
|
u32 type;
|
|
};
|
|
|
|
/*
|
|
* .klp.symid is used to correlate symbols between vmlinux.o and vmlinux, for
|
|
* calculating sympos to disambiguate duplicately-named symbols.
|
|
*/
|
|
#define KLP_SYMID_SEC ".klp.symid"
|
|
|
|
struct klp_symid {
|
|
u64 id;
|
|
u64 addr;
|
|
};
|
|
|
|
struct objtool_file;
|
|
struct elf;
|
|
struct symbol;
|
|
|
|
int klp_create_symid_sections(struct objtool_file *file);
|
|
|
|
int klp_sympos_init(struct elf *orig);
|
|
unsigned long klp_find_sympos(struct elf *elf, struct symbol *sym);
|
|
|
|
int cmd_klp_checksum(int argc, const char **argv);
|
|
int cmd_klp_diff(int argc, const char **argv);
|
|
int cmd_klp_post_link(int argc, const char **argv);
|
|
|
|
#endif /* _OBJTOOL_KLP_H */
|