* [PATCH] objtool/klp: Fix detection of static keys defined in other files
@ 2026-10-06 7:10 Song Liu
0 siblings, 0 replies; only message in thread
From: Song Liu @ 2026-10-06 7:10 UTC (permalink / raw)
To: live-patching; +Cc: jpoimboe, jikos, mbenes, pmladek, joe.lawrence, Song Liu
validate_special_section_klp_reloc() finds the key of a __jump_table or
.static_call_sites entry by looking for a reloc to an STT_OBJECT symbol.
But a key is STT_OBJECT only in the object file which defines it. In
any other object file it is an undefined symbol, which is STT_NOTYPE,
and the check misses it. For example, with tracepoint keys:
Patched file Tracepoint Key defined in Type
---------------------- ------------------ ------------------- ------
vmlinux:
kernel/sched/core.c sched_switch same file OBJECT
kernel/sched/fair.c sched_stat_runtime kernel/sched/core.c NOTYPE
kvm.ko:
arch/x86/kvm/x86.c kvm_msr same file OBJECT
arch/x86/kvm/lapic.c kvm_apic_ipi arch/x86/kvm/x86.c NOTYPE
cachefiles.ko:
fs/cachefiles/io.c netfs_sreq vmlinux NOTYPE
kvm-intel.ko:
arch/x86/kvm/vmx/vmx.c kvm_exit kvm.ko NOTYPE
Missing a key in vmlinux is harmless, as the check accepts vmlinux keys
anyway. Their entries are cloned with a normal reloc to the key if
vmlinux exports it to all modules, as for netfs_sreq, and with a klp
reloc otherwise, which the module loader applies before it initializes
the livepatch module's static branches and static calls.
But a livepatch can't use a key defined in a module, so klp-diff has to
disable such tracepoints, as it does for kvm_msr above. For keys
defined in another file of the same module, as for kvm_apic_ipi, or in
another module, as for kvm_exit, it instead clones the entries with klp
relocs for their keys.
The resulting patch module crashes the kernel on load. The livepatch
module's static calls and static branches get initialized while their key
fields still wait for the klp relocs. The static call init rewrites the
call instruction, so applying its klp reloc fails:
module: x86/modules: Invalid relocation target, existing value is nonzero for sec 66, idx 16, type 4, loc ffffffffa04021f3, val ffffffffffffe0f5
and static_call_del_module() then dereferences the bogus key while
cleaning up after the failed init:
BUG: unable to handle page fault for address: ffffffffa2373994
RIP: 0010:static_call_del_module+0x38/0x80
Call Trace:
static_call_module_notify+0x42/0x1a0
notifier_call_chain+0x5f/0xd0
blocking_notifier_call_chain+0x41/0x60
do_init_module+0x23d/0x2a0
Also treat undefined symbols as keys. The other relocs of these entries
refer to code in the patched object, which is always defined.
Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Song Liu <song@kernel.org>
---
tools/objtool/klp-diff.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index 34da55e45609..cbc475d79156 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -1862,8 +1862,13 @@ static int validate_special_section_klp_reloc(struct elfs *e, struct symbol *sym
if (convert_reloc_sym(e->patched, reloc))
continue;
- /* Static branch/call keys are always STT_OBJECT */
- if (reloc->sym->type != STT_OBJECT) {
+ /*
+ * Static branch/call keys are STT_OBJECT if they're defined
+ * in this object file. Keys defined in another file, whether
+ * in vmlinux, the same module or another module, are undefined
+ * symbols, which are STT_NOTYPE.
+ */
+ if (reloc->sym->type != STT_OBJECT && !is_undef_sym(reloc->sym)) {
/* Save code location which can be printed below */
if (reloc->sym->type == STT_FUNC && !code_sym) {
--
2.53.0-Meta
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-06 7:10 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-06 7:10 [PATCH] objtool/klp: Fix detection of static keys defined in other files Song Liu
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.