| d8a2860b | 15-Aug-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Fix vmlinux klp relocations for EXPORT_SYMBOL_FOR_MODULES()
When a module function references a vmlinux symbol which is exported with EXPORT_SYMBOL_FOR_MODULES(), a patch to that functi
objtool/klp: Fix vmlinux klp relocations for EXPORT_SYMBOL_FOR_MODULES()
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.
Commit 07f14d6af9d77 ("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: 07f14d6af9d77 ("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
show more ...
|
| 7df1638d | 09-Aug-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Fix .kcfi_traps special section extraction
create_fake_symbols() creates a symbol per entry for special sections. It does so in two steps: first for the sections which have ANNOTATE_DAT
objtool/klp: Fix .kcfi_traps special section extraction
create_fake_symbols() creates a symbol per entry for special sections. It does so in two steps: first for the sections which have ANNOTATE_DATA_SPECIAL annotations, then for the rest, using entsize or the reloc count to infer the entry size. The second step skips the sections already handled by the first one by looking for a symbol at offset 0.
That heuristic is too fuzzy: with Clang and CONFIG_CFI, it misfires on .kcfi_traps because Clang emits a .Ltmp* assembler-local label at the start of the section, so no symbols are created and clone_special_sections() extracts nothing. klp-build still reports SUCCESS, but the livepatch module has no __kcfi_traps section and the traps for the patched functions are lost.
Look for the actual fake symbols created by the first step instead.
Fixes: da4326573ae8d ("objtool/klp: Fix kCFI trap handling") Reported-by: Joe Lawrence <joe.lawrence@redhat.com> Closes: https://lore.kernel.org/r/akQNqlfFC0T5pcMa@redhat.com Acked-by: Song Liu <song@kernel.org> Link: https://patch.msgid.link/8faaead205b219607b6fc2359ae743be824056eb.1786230311.git.jpoimboe@kernel.org Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| 07f14d6a | 07-Aug-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Fix cross-module klp relocation section naming
A klp relocation section is .klp.rela.<objname>.<secname>, where objname is the object being patched.
klp-build wrongly derives objname f
objtool/klp: Fix cross-module klp relocation section naming
A klp relocation section is .klp.rela.<objname>.<secname>, where objname is the object being patched.
klp-build wrongly derives objname from where the referenced symbol lives, not where it's referenced. For a cross-module reference like patched can_isotp code calling can.ko's can_rx_unregister(), that gives .klp.rela.can..text rather than .klp.rela.can_isotp..text. Unless the patch happens to patch can.ko as well, the relocation never gets applied and the call goes off into the weeds.
Name the intermediate section __klp_relocs.<objname> so post-link can read the patched object's name from there.
Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files") Reported-by: Joe Lawrence <joe.lawrence@redhat.com> Link: https://lore.kernel.org/20260720145658.1103243-2-joe.lawrence@redhat.com Acked-by: Song Liu <song@kernel.org> Acked-by: Joe Lawrence <joe.lawrence@redhat.com> Link: https://patch.msgid.link/ee93a08f3e55e76ffa67d04e283917ddaa893f09.1786138493.git.jpoimboe@kernel.org Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| 636f230c | 07-Aug-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Ignore replacement offset of empty x86 alternatives
An x86 alternative with an empty replacement, e.g. the second entry of
ALTERNATIVE_2("orig", "repl", ft1, "", ft2)
has a replacem
objtool/klp: Ignore replacement offset of empty x86 alternatives
An x86 alternative with an empty replacement, e.g. the second entry of
ALTERNATIVE_2("orig", "repl", ft1, "", ft2)
has a replacementlen of zero. Its replacement offset still gets a relocation, but the label it points at is the end of the previous replacement, which is also the beginning of the *next* alternative's replacement. The value is meaningless; get_alt_entry() already ignores it for that reason.
klp diff doesn't ignore it. When such an alternative belongs to a changed function, cloning its relocations drags in the unrelated neighboring replacement, along with everything that replacement references. On an x86 clang/lto build an empty alternative in meminfo_proc_show() pulled in the replacement of an alternative in proc_kcore_init(), silently emitting a klp relocation against init text which has long since been freed by the time the patch is applied.
Add arch_alt_ignore_new_reloc() and skip such relocations when cloning. This has to be arch specific: on arm64 a zero-length replacement instead identifies an alternative callback, whose replacement offset points at the callback function and must be preserved.
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/7a885b70974795c3417f3358869e62aafd4ef783.1786138493.git.jpoimboe@kernel.org Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| 15fa203e | 03-Aug-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Fix symbol resolution for duplicate data symbols
find_sympos() calculates a sympos used by livepatch to disambiguate duplicately-named symbols. For function symbols, there's a hack whi
objtool/klp: Fix symbol resolution for duplicate data symbols
find_sympos() calculates a sympos used by livepatch to disambiguate duplicately-named symbols. For function symbols, there's a hack which counts .text.unlikely symbols before other .text symbols, matching the linker script's section ordering.
Not only is the hack fragile, data symbols can have the same problem. So for example, adding a reference to pwq_cache in ep_unregister_pollwait() can trigger a corrupt sympos and a relocation to the wrong pwq_cache symbol in the livepatch module, resulting in a crash or undefined behavior.
Remove the existing hack in favor of a fully deterministic solution, using the new .klp.symid table to derive the symbol-to-id mapping from the original vmlinux.o and the id-to-address mapping from the corresponding vmlinux, which can then be used to determine the exact sympos associated with the original vmlinux.
Modules don't need any special treatment: the .ko has the same section/symbol ordering as the original whole-archive symbol table.
Fixes: dd590d4d57eb ("objtool/klp: Introduce klp diff subcommand for diffing object files") Reported-by: Ben Procknow <bprockno@redhat.com> Reported-by: Joe Lawrence <joe.lawrence@redhat.com> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: live-patching@vger.kernel.org Link: https://lore.kernel.org/20260710153042.3156788-1-joe.lawrence@redhat.com Link: https://lore.kernel.org/20260724221730.3126529-1-joe.lawrence@redhat.com Link: https://patch.msgid.link/919785e3bf2245db02ff6391e735d9cb139170b1.1785727106.git.jpoimboe@kernel.org
show more ...
|
| 029223d3 | 03-Aug-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Add .klp.symid for sympos disambiguation
Livepatch identifies a duplicate-named symbol by its position (sympos) among same-named kallsyms entries, which for vmlinux are counted in ascen
objtool/klp: Add .klp.symid for sympos disambiguation
Livepatch identifies a duplicate-named symbol by its position (sympos) among same-named kallsyms entries, which for vmlinux are counted in ascending address order in the final linked kernel. That order can't be reliably derived from vmlinux.o: the final link reorders sub-sections (.text.unlikely*, .data..*, etc).
Bridge the gap with a new .klp.symid section which can be used to correlate symbols between vmlinux.o and vmlinux so that klp-diff can reliably determine the sympos.
The table can't survive --gc-sections: keeping it alive would keep every duplicate-named symbol's section alive, so the reference kernel would stop matching the one which ships. klp-build rejects CONFIG_LD_DEAD_CODE_DATA_ELIMINATION instead. Nothing is lost today: x86_64 is the only HAVE_KLP_BUILD arch and doesn't select HAVE_LD_DEAD_CODE_DATA_ELIMINATION, arm64 and s390 have never selected it either, and on powerpc, it's still EXPERIMENTAL and disabled by every distro kernel.
This is the build-time half of reliable vmlinux sympos computation; "objtool klp diff" will consume the table in a subsequent commit.
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: live-patching@vger.kernel.org Link: https://patch.msgid.link/64d50f077b569f47883c015cdb7079edb068efe8.1785727106.git.jpoimboe@kernel.org
show more ...
|
| 2d3bb398 | 20-Apr-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Cache dont_correlate() result
Cache the dont_correlate() result once per symbol at the start of correlate_symbols(). This reduces klp diff time on an arm64 LTO vmlinux.o from 2m51s to
objtool/klp: Cache dont_correlate() result
Cache the dont_correlate() result once per symbol at the start of correlate_symbols(). This reduces klp diff time on an arm64 LTO vmlinux.o from 2m51s to 35s.
Acked-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| f7ceffd2 | 28-Apr-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Fix kCFI prefix finding/cloning
With CFI+CALL_PADDING, Clang places .Ltmp labels at the start of the NOP padding (offset 5) between the __cfi_ prefix and the function entry point. get_
objtool/klp: Fix kCFI prefix finding/cloning
With CFI+CALL_PADDING, Clang places .Ltmp labels at the start of the NOP padding (offset 5) between the __cfi_ prefix and the function entry point. get_func_prefix() only checks the immediately previous symbol, so the intervening .Ltmp label causes it to miss the __cfi_ prefix symbol.
This results in klp-diff not cloning the kCFI type hash into the livepatch module, causing a CFI failure at module load when calling callback functions through indirect calls:
CFI failure at __klp_enable_patch+0xab/0x140 (target: pre_patch_callback+0x0/0x80 [livepatch_combined]; expected type: 0xde073954)
Instead of walking backward through the section's symbol list, just use find_func_containing() for the byte before the function. This works now that __cfi_ symbols are being grown by objtool to fill the padding.
Acked-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| fc0bb991 | 24-Apr-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool: Grow __cfi_* prefix symbols for all CFI+CALL_PADDING
For all CONFIG_CFI+CONFIG_CALL_PADDING configs, for C functions, the __cfi_ symbols only cover the 5-byte kCFI type hash. After that th
objtool: Grow __cfi_* prefix symbols for all CFI+CALL_PADDING
For all CONFIG_CFI+CONFIG_CALL_PADDING configs, for C functions, the __cfi_ symbols only cover the 5-byte kCFI type hash. After that there also N bytes of NOP padding between the hash and the function entry which aren't associated with any symbol.
The NOPs can be replaced with actual code at runtime. Without a symbol, unwinders and tooling have no way of knowing where those bytes belong.
Grow the existing __cfi_* symbols to fill that gap.
Note that assembly functions with SYM_TYPED_FUNC_START() aren't affected by this issue, their __cfi_ symbols also cover the padding.
Also, CONFIG_PREFIX_SYMBOLS has no reason to exist: CONFIG_CALL_PADDING is what causes the compiler to emit NOP padding before function entry (via -fpatchable-function-entry), so it's the right condition for creating prefix symbols.
Remove CONFIG_PREFIX_SYMBOLS, as it's no longer needed. Simplify the LONGEST_SYM_KUNIT_TEST dependency accordingly. Rework objtool's arguments a bit to handle the variety of prefix/cfi-related cases.
Suggested-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| cca84cb1 | 03-Apr-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Fix position-dependent checksums for non-relocated jumps/calls
When computing klp checksums, instructions with non-relocated jump/call destination offsets are problematic because the of
objtool/klp: Fix position-dependent checksums for non-relocated jumps/calls
When computing klp checksums, instructions with non-relocated jump/call destination offsets are problematic because the offset values can change when surrounding code has moved, causing the function to be incorrectly marked as changed.
Specifically, that includes jumps from alternatives to the end of the alternative, which from objtool's perspective are jumps to the end of the alternative instruction block in the original function.
Note that 'jump_dest' jumps don't include sibling calls (those use call_dest), nor do they include jumps to/from .cold sub functions (those are cross-section and need a reloc).
Fix it by hashing the opcode bytes (excluding the immediate operand) along with a position-independent representation of the destination. For calls, use the function name, and for jumps, use the destination's offset within its function.
[Note the "9 bit hole" comment was wrong: it has been 8 bits since commit 70589843b36f ("objtool: Add option to trace function validation") added the 'trace' field. Adding the 4-bit 'immediate_len' field now leaves a 4-bit hole.]
Fixes: 0d83da43b1e1 ("objtool/klp: Add --checksum option to generate per-function checksums") Acked-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| 3ee67629 | 04-Apr-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool: Add insn_sym() helper
Alternative replacement instructions awkwardly have insn->sym set to the function they get patched to rather than the symbol (or rather lack thereof) they belong to in
objtool: Add insn_sym() helper
Alternative replacement instructions awkwardly have insn->sym set to the function they get patched to rather than the symbol (or rather lack thereof) they belong to in the file.
This makes it difficult to know where a given instruction actually lives.
Add a new insn_sym() helper which preserves the existing semantic of insn->sym. Rename insn->sym to insn->_sym, which contains the actual ELF binary symbol (or NULL, for alternative replacements) an instruction lives in.
The private insn->_sym value will be needed for a subsequent patch.
Acked-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| 5d6a03ee | 21-Apr-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Add correlation debugging output
Add debugging messages to show how duplicate symbols get correlated, and split the --debug feature into --debug-correlate and --debug-clone.
Acked-by:
objtool/klp: Add correlation debugging output
Add debugging messages to show how duplicate symbols get correlated, and split the --debug feature into --debug-correlate and --debug-clone.
Acked-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| e1076461 | 03-Apr-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Add "objtool klp checksum" subcommand
Move the checksum functionality out of the main objtool command into a new "objtool klp checksum" subcommand.
This has the benefit of making the c
objtool/klp: Add "objtool klp checksum" subcommand
Move the checksum functionality out of the main objtool command into a new "objtool klp checksum" subcommand.
This has the benefit of making the code (and the patch generation process itself) more modular.
For bisectability, both "objtool --checksum" and "objtool klp checksum" work for now. The former will be removed after klp-build has been converted to use the new subcommand.
Acked-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| a5b66123 | 03-Apr-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool: Consolidate file decoding into decode_file()
decode_sections() relies on CFI and cfi_hash initialization done separately in check(), making it unusable outside of check().
Consolidate the
objtool: Consolidate file decoding into decode_file()
decode_sections() relies on CFI and cfi_hash initialization done separately in check(), making it unusable outside of check().
Consolidate the initialization into decode_sections() and rename it to decode_file(), and make it global along with free_insns() and insn_reloc() for use by other objtool components -- namely, the checksum code which will be moving to another file.
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| 30cae58c | 03-Apr-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Extricate checksum calculation from validate_branch()
In preparation for porting the checksum code to other arches, make its functionality independent from the CFG reverse engineering c
objtool/klp: Extricate checksum calculation from validate_branch()
In preparation for porting the checksum code to other arches, make its functionality independent from the CFG reverse engineering code.
Move it into a standalone calculate_checksums() function which iterates all functions and instructions directly, rather than being called inline from do_validate_branch().
Since checksum_update_insn() is no longer called during CFG traversal, it needs to manually iterate the alternatives.
Acked-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| d5b0f025 | 28-Apr-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Fix pointer comparisons for rodata objects
klp-diff treats all rodata as uncorrelated, so any reference to it uses a duplicated copy rather than using a KLP reloc.
For the contents of
objtool/klp: Fix pointer comparisons for rodata objects
klp-diff treats all rodata as uncorrelated, so any reference to it uses a duplicated copy rather than using a KLP reloc.
For the contents of the data itself, a duplicated copy is fine. However, pointer comparisons (e.g., f->f_op == &foo_ops) are broken.
Fix it by correlating non-anonymous rodata objects.
Also, use a new find_symbol_containing_inclusive() helper for matching the end of a symbol so bounds calculations don't get broken, for the case where an array or other symbol's ending address is used as part of a bounds calculation.
While these are really two distinct changes, they need to be done in the same patch so as to avoid introducing bisection regressions.
Acked-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| 3e01ab44 | 13-Apr-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool: Move mark_rodata() to elf.c
Move the sec->rodata marking from check.c to elf.c so it's set during ELF reading rather than during the check pipeline. This makes the rodata flag available to
objtool: Move mark_rodata() to elf.c
Move the sec->rodata marking from check.c to elf.c so it's set during ELF reading rather than during the check pipeline. This makes the rodata flag available to all objtool users, including klp-diff which reads ELF files directly without running check().
Add an is_rodata_sec() helper to elf.h for consistency with is_text_sec() and is_string_sec().
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Song Liu <song@kernel.org> Reviewed-by: Miroslav Benes <mbenes@suse.cz> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| 479ac526 | 03-Apr-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Fix XXH3 state memory leak
The XXH3 state allocated in checksum_init() is never freed. Free it in checksum_finish().
Acked-by: Song Liu <song@kernel.org> Reviewed-by: Miroslav Benes <
objtool/klp: Fix XXH3 state memory leak
The XXH3 state allocated in checksum_init() is never freed. Free it in checksum_finish().
Acked-by: Song Liu <song@kernel.org> Reviewed-by: Miroslav Benes <mbenes@suse.cz> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|
| def5b60d | 31-Mar-2026 |
Josh Poimboeuf <jpoimboe@kernel.org> |
objtool/klp: Fix --debug-checksum for duplicate symbol names
find_symbol_by_name() only returns the first match, so --debug-checksum=<func> silently ignores any subsequent duplicately named function
objtool/klp: Fix --debug-checksum for duplicate symbol names
find_symbol_by_name() only returns the first match, so --debug-checksum=<func> silently ignores any subsequent duplicately named functions after the first.
Fix that, along with a new for_each_sym_by_name() helper.
Acked-by: Song Liu <song@kernel.org> Reviewed-by: Miroslav Benes <mbenes@suse.cz> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
show more ...
|