From: Song Liu <song@kernel.org>
To: live-patching@vger.kernel.org
Cc: jpoimboe@kernel.org, jikos@kernel.org, mbenes@suse.cz,
pmladek@suse.com, joe.lawrence@redhat.com,
Song Liu <song@kernel.org>
Subject: [PATCH] objtool/klp: Fix detection of static keys defined in other files
Date: Tue, 6 Oct 2026 00:10:03 -0700 [thread overview]
Message-ID: <20261006071003.291679-1-song@kernel.org> (raw)
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
reply other threads:[~2026-10-06 7:10 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261006071003.291679-1-song@kernel.org \
--to=song@kernel.org \
--cc=jikos@kernel.org \
--cc=joe.lawrence@redhat.com \
--cc=jpoimboe@kernel.org \
--cc=live-patching@vger.kernel.org \
--cc=mbenes@suse.cz \
--cc=pmladek@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.