| 94553727 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for ThinLTO symbols sharing a demangled name
A file-local symbol which ThinLTO has to make visible is renamed helper.llvm.<hash>. With two such helpers in one link, the origin
objtool/klp: Add test for ThinLTO symbols sharing a demangled name
A file-local symbol which ThinLTO has to make visible is renamed helper.llvm.<hash>. With two such helpers in one link, the original and the patched object hold two each, all four spelled differently, and demangling gives "helper" for every one of them -- so the name alone cannot say which corresponds to which.
Three translation units, two with a static helper of the same name and a third calling into both, which is what forces the promotion. Only one helper changes: paired correctly that means exactly one is cloned, and paired the wrong way round the other is, or both are. Had both bodies changed, both would be cloned either way and the test would prove nothing -- which is how the first version of this was written.
The outcome is asserted, not the machinery. With the clang tested here the pairing survives disabling the .llvm.<hash> suffix map and stubbing out llvm_suffix() entirely, so no single-line sabotage distinguishes it; the tiered matcher this case was written for is not needed for this shape. The test says so rather than implying otherwise.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-59-song@kernel.org
show more ...
|
| 317cf7bb | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for Clang switch jump tables
For a dense enough switch Clang emits the targets as a table in .rodata..Lswitch.table.<function> -- named after the function but not part of it.
objtool/klp: Add test for Clang switch jump tables
For a dense enough switch Clang emits the targets as a table in .rodata..Lswitch.table.<function> -- named after the function but not part of it. The patched function indexes into that table, so a clone which does not bring it along jumps through whatever the kernel's copy holds, which after a patch that changed the switch is the wrong set of targets. An indirect jump to a stale address reports nothing at build or load time.
The fixture asserts its own premise twice over, since both halves depend on what this Clang chose to do: that a table was built rather than a chain of comparisons, and that the added case actually changed it.
objtool has no switch-specific code -- the table is carried by the general mechanism for data a cloned function references -- so this guards that mechanism reaching an easily-mishandled shape rather than a particular line, and the test says so. Making the table uncorrelated, the nearest available sabotage, does not change the outcome.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-58-song@kernel.org
show more ...
|
| 41ca5150 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for UBSAN metadata in an unchanged function
Every instrumented operation gets a per-callsite metadata object in an anonymous data section -- .data..Lubsan_data and .data..Lubsa
objtool/klp: Add test for UBSAN metadata in an unchanged function
Every instrumented operation gets a per-callsite metadata object in an anonymous data section -- .data..Lubsan_data and .data..Lubsan_type from GCC, .data..L__unnamed_ from Clang -- whose names are compiler-generated and mean nothing across a rebuild. is_uncorrelated_section() exists so klp diff does not try to pair them up, and nothing tested it.
The failure it prevents is a false positive, which is the direction this suite has least coverage of. Metadata belonging to a function nobody touched compares as different and drags that function into the patch. That is not a build failure: it is a larger livepatch than intended, pulling in dependencies with it, and every extra function is one more that can fail to correlate or to apply.
The fixture is built with -fsanitize=shift, which both compilers instrument; neither emits a bounds check for an index it can prove in range. One function changes, the other is byte-identical and carries instrumentation of its own, and the test asserts the second is left alone.
Verified by removing each rule from is_uncorrelated_section() in turn, which splits neatly by toolchain: dropping the .data..Lubsan rule fails the test under gcc, dropping .data..L__unnamed_ fails it under clang. One test, two code paths, each checked by the compiler that reaches it.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-57-song@kernel.org
show more ...
|
| 91c67484 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for absolute and __ADDRESSABLE symbols
A SHN_ABS symbol has no section, so any walk of sym->sec which does not check dereferences NULL, and the kernel has plenty of them -- fro
objtool/klp: Add test for absolute and __ADDRESSABLE symbols
A SHN_ABS symbol has no section, so any walk of sym->sec which does not check dereferences NULL, and the kernel has plenty of them -- from linker scripts and from .set in assembly. __ADDRESSABLE() emits a pointer into .discard.addressable purely to keep a symbol referenced; it means nothing to a livepatch and is discarded at link time, but it is a relocation like any other and gets looked at.
Neither is what the patch changes. What this guards against is not a wrong answer but a crash or an error on input the kernel produces routinely, which would make every function near one unpatchable.
Not isolated to a single line, and the test says so: the absolute symbol here has zero length, so it is excluded before the section check is reached and removing that check alone changes nothing observable.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-56-song@kernel.org
show more ...
|
| 794b162b | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for a patch which strips a data annotation
klp diff needs entry boundaries for a special section: either an entsize, or ANNOTATE_DATA_SPECIAL annotations naming where each entr
objtool/klp: Add test for a patch which strips a data annotation
klp diff needs entry boundaries for a special section: either an entsize, or ANNOTATE_DATA_SPECIAL annotations naming where each entry starts. .static_call_sites has no entsize, so the annotations are all there is -- and a patch can remove the last one in a translation unit while leaving the section itself in place, so that only the patched side has lost them.
The section still has to be handled. Dropping it leaves the patched function's static call unregistered; misreading its boundaries attaches the entry to the wrong code. Neither is reported at build time.
Give the fixture a NO_ANNOTATE knob and assert the premise -- annotation present in the original, absent in the patched object, section present in both -- before asserting the result.
Fixed by commit 3de711fba73a ("objtool/klp: Fix create_fake_symbols() skipping entsize-based sections"). Verified by making klp diff skip .static_call_sites when cloning special sections: the test fails.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-55-song@kernel.org
show more ...
|
| 8abe5c94 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for the alignment of cloned data sections
A cloned data section has to keep its sh_addralign. Plenty of kernel data is aligned for correctness rather than speed -- per-CPU var
objtool/klp: Add test for the alignment of cloned data sections
A cloned data section has to keep its sh_addralign. Plenty of kernel data is aligned for correctness rather than speed -- per-CPU variables, anything touched by an aligned vector move, structures padded to own a cacheline -- and a clone that lands under-aligned either faults on first use or silently shares a line it was laid out to avoid. Neither shows up until the patch is loaded on hardware that cares.
The fixture's data is new in the patched build, so klp diff has to clone it rather than reference the kernel's copy, and it asserts that premise before asserting the result.
Commit 2f2600decb30 ("objtool/klp: fix data alignment in __clone_symbol()") cannot be reverted to check this -- the revert is a no-op against the current code, which has been rewritten since. Verified instead by forcing the clone's alignment to 1, which the test reports as "alignment 1, expected 64".
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-54-song@kernel.org
show more ...
|
| 32b2cf11 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for alternative replacement code in checksums
checksum_update_insn() walks insn->alts after hashing the instruction itself: the alternative's type, and where the replacement fo
objtool/klp: Add test for alternative replacement code in checksums
checksum_update_insn() walks insn->alts after hashing the instruction itself: the alternative's type, and where the replacement forms a group, its feature number and every instruction in it. A patch which edits only the replacement -- code that runs on some CPUs and not others -- still has to move the function's checksum.
When it does not, klp diff calls the function unchanged and leaves it out. The patch ships the old replacement, and the bug is fixed only on machines whose CPU takes the other arm. Which machines those are depends on the feature bit, so it presents as a machine-specific bug rather than a missing patch.
insn->alts is built by objtool's check pass, not by the compiler, so the pair goes through that first. --mcount is the action used: it is the cheapest one that does not also need --link.
Two of the three paths are isolated. Skipping the alts walk and dropping the feature hash both make this fail, and the second of those only exists inside the alt_group branch, so reaching it proves the grouped path is taken. The alternative's type is hashed but not varied here -- the fixture emits one kind of alternative -- so that line is covered without being isolated, as is the in_alt recursion guard, which wants nested alternatives.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-53-song@kernel.org
show more ...
|
| 065f09c8 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for instruction operand checksums
checksum_update_insn() hashes an instruction's bytes and then what any relocation on it refers to: a string section contributes the string's c
objtool/klp: Add test for instruction operand checksums
checksum_update_insn() hashes an instruction's bytes and then what any relocation on it refers to: a string section contributes the string's contents, anything else the target symbol's name and adjusted addend, with a reference to a static resolved through its section symbol first.
None of that shows up in the bytes. A rel32 operand is zero in the object and supplied by the relocation, so calling a different function, editing a literal the code passes, or reading a different index of an array all leave the encoded instruction byte-identical. A checksum stopping at the bytes reports the function unchanged and the patch silently does not contain the fix.
test-checksum-position is the other half: what must *not* change the checksum when a function merely moves.
Each of the four is verified by sabotaging the line it covers. The static case needed a writer the compiler cannot see through -- without one it proves the array is never written, folds every read to zero, and emits no relocation at all, so the reference under test does not exist and the variant passes having compared two identical objects.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-52-song@kernel.org
show more ...
|
| 938816b7 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for a static call introduced by the patch
The counterpart to the static branch case: a patch may add a static call to a function which had none, so the .static_call_sites entry
objtool/klp: Add test for a static call introduced by the patch
The counterpart to the static branch case: a patch may add a static call to a function which had none, so the .static_call_sites entry is new and there is nothing in the original to correlate it against.
Where the key lives still decides whether that is allowed. A vmlinux key is reachable; a module-owned one is not, for the same reason an existing module key is not -- late module patching lets the livepatch load first and the unresolved entry is dereferenced when the module arrives. Both halves are here because they fail in opposite directions: dropping the new entry leaves a static call the kernel never patches, and accepting a new module-owned one is the corruption the check exists to prevent.
Both halves are one test over one fixture: built with -DNEW_CALL the key is vmlinux's and the new entry has to be carried in; built with -DMODNAME as well the key belongs to a module, klp diff has to reject it, and no output object may be left behind. The premise is asserted first -- the original must have no .static_call_sites at all -- since otherwise this is a second copy of test-static-call-module-key.
Covers the same ground as corpus/x86_64/static-call-vmlinux-new and corpus/x86_64/static-call-module-new in Joe Lawrence's klp-build unit test corpus.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-51-song@kernel.org
show more ...
|
| 2f4bbb1c | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for tracepoint and pr_debug static branch keys
A module-owned static branch key is normally fatal, because late module patching lets the livepatch load before the module it dep
objtool/klp: Add test for tracepoint and pr_debug static branch keys
A module-owned static branch key is normally fatal, because late module patching lets the livepatch load before the module it depends on and jump_label_add_module() then dereferences an unresolved entry.
Tracepoints and pr_debug() generate such keys everywhere, so refusing them outright would make any function containing a trace_*() call or a pr_debug() unpatchable. klp diff drops the entry, warns, and carries on: the patched code works with that one tracepoint or debug print permanently off.
Both halves matter, and the test asserts both. A build which fails is a function nobody can patch; an entry left in place is the corruption the rejection exists to prevent.
Give the fixture a KEY_NAME knob so the same static branch can be built with either special name. Verified by removing each exemption in turn -- the test fails for both. That the entry is then dropped is asserted but not isolated, and the test says so.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-50-song@kernel.org
show more ...
|
| 8fc5ddd4 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for a static branch introduced by the patch
Patching a function which already has a static branch and adding one to a function which had none are different cases. In the secon
objtool/klp: Add test for a static branch introduced by the patch
Patching a function which already has a static branch and adding one to a function which had none are different cases. In the second the __jump_table entry is itself new, so there is nothing in the original to correlate it against: klp diff has to carry the entry into the patch from scratch and reach the key the way it reaches any other vmlinux symbol.
Dropping it is silent. The patched function keeps a static branch the kernel never patches, so it takes the same arm forever whatever the key is set to.
Give the fixture a NEW_KEY knob which puts the whole branch behind PATCHED, and assert the premise -- that the original really has no __jump_table -- before asserting the result, since otherwise this is just a second copy of test-jump-label-key.
Verified by making klp diff skip __jump_table when cloning special sections: the test fails.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-49-song@kernel.org
show more ...
|
| c8304204 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for symbols with no checksum entry of their own
.discard.sym_checksum is an array of { address, checksum } looked up by the address a relocation points at, so the invariant is
objtool/klp: Add test for symbols with no checksum entry of their own
.discard.sym_checksum is an array of { address, checksum } looked up by the address a relocation points at, so the invariant is one entry per address. calculate_checksums() skips zero-length symbols, aliases and cold parts to keep it, and nothing checked that it does.
A duplicate entry is not a build failure. It makes the lookup ambiguous, and whichever checksum loses is never consulted again -- so a function whose code changed can be read as unchanged and dropped from the patch.
The alias skip is verified the usual way: remove it and the test fails. The other two are not isolated, and the test says so rather than implying otherwise. A zero-length symbol is excluded by several of the guards at once -- its section has no data either -- so removing any one of them changes nothing observable; the assertion stands as a check on the behaviour, not on the line that produces it. The cold-part skip needs a compiler that splits functions and is not reached here at all.
Which of an aliased pair keeps the entry falls out of symbol table order, so the test requires exactly one of the two rather than naming a winner -- as written first it named real_function and failed, because gcc kept the alias.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-48-song@kernel.org
show more ...
|
| ac324798 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for data object checksums
klp checksum hashes a data symbol's length, its bytes, and every relocation it carries -- as the target's name and adjusted addend, except a reference
objtool/klp: Add test for data object checksums
klp checksum hashes a data symbol's length, its bytes, and every relocation it carries -- as the target's name and adjusted addend, except a reference into a string section, which contributes the string's contents instead. Nothing covered any of it.
Each is load-bearing, and the failure is always the same shape: a checksum which ignores one calls a changed object unchanged, klp diff leaves it out of the patch, and the patched code goes on reading the kernel's old copy. The string case cannot be caught by hashing bytes: the pointer is identical, same section and same offset, and only the text it refers to moved.
One fixture, six variants applied to the patched build alone. Each was verified by sabotaging the line it covers and watching the test fail:
raw bytes initialiser change length a .bss object grows; its bytes are never hashed string contents literal edited in place, pointer untouched reloc target name pointer moved to another function reloc addend same array, different index section-symbol path the same, via a static's section symbol
Two of those needed the fixture rebuilding. An initialised array does not isolate the length, because growing one changes the hashed bytes too -- hence .bss, where there are none. And a named char[] does not reach the contents-hashing path at all: that keys on SHF_STRINGS, which the compiler sets on the mergeable section a literal lands in and not on an array given a section of its own.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-47-song@kernel.org
show more ...
|
| c4717a16 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Test text annotations on alternative replacements
The kernel annotates instructions inside an ALTERNATIVE's replacement wherever objtool has to be told something about them -- a retpoli
objtool/klp: Test text annotations on alternative replacements
The kernel annotates instructions inside an ALTERNATIVE's replacement wherever objtool has to be told something about them -- a retpoline-safe indirect branch, a deliberately absent ENDBR. klp diff dropped those annotations, for two reasons: replacement code has no real symbol, so the NOTYPE fake symbol objtool invents for it was not recognised as worth keeping a reference to, and .discard.annotate_insn was processed before .altinstructions, so the replacement it named had no clone yet.
Nothing fails at build time when the annotation goes missing. It surfaces later as objtool warning about, or rejecting, the very code the annotation was there to explain.
The fixture keeps the replacement label global, as empty_alternative.c does, so the relocations name it instead of .altinstr_replacement plus an addend -- which klp diff rejects outright. The label is still NOTYPE, which is the property under test. The test asserts the relocation as well as the section, since an entry whose relocation was dropped would otherwise pass.
Verified by reverting commit 62a7a01fde87 ("objtool/klp: Fix extraction of text annotations for alternatives"): the output has no .discard.annotate_insn at all and the test fails, under both gcc and clang.
Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Assisted-by: Claude:claude-opus-5 Link: https://patch.msgid.link/20260916184351.2720310-46-song@kernel.org
show more ...
|
| 841c8c57 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Test a hand-built livepatch module's static call keys
__SCK__* static call keys are not exported; modules are given read-only access at load time. Livepatch modules built by klp-build
objtool/klp: Test a hand-built livepatch module's static call keys
__SCK__* static call keys are not exported; modules are given read-only access at load time. Livepatch modules built by klp-build do have full access to theirs, and commit 164c9201e1da ("objtool: Add base objtool support for livepatch modules") added a check on that basis -- but a livepatch module can also be written by hand, as everything under samples/livepatch is, and such a module hits an unexported key as soon as it does anything expanding to a static call. With CONFIG_MEM_ALLOC_PROFILING_DEBUG that includes allocating memory, which is how livepatch-shadow-fix1 came to fail to build.
Cover it, with the plain module as a control: it takes the same path and has always been accepted, so a test that built only the livepatch variant could not tell this fix from the check being deleted.
This is objtool's ordinary check pass rather than a klp subcommand, which is the first test here to exercise it -- and is the point, since that pass is what runs over a hand-built livepatch module during a normal kernel build.
Verified by reverting commit f495054bd12e ("objtool/klp: Fix unexported static call key access for manually built livepatch modules"): objtool reports "can't find static_call_key symbol: __SCK__klp_test_call" and the test fails, under both gcc and clang.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-45-song@kernel.org
show more ...
|
| 58b0d663 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Test rejection of a file-local static branch key
A static branch key owned by a module cannot be reached with a klp reloc: late module patching allows the livepatch module to load first
objtool/klp: Test rejection of a file-local static branch key
A static branch key owned by a module cannot be reached with a klp reloc: late module patching allows the livepatch module to load first, leaving the __jump_table entry unresolved for jump_label_add_module() to dereference. validate_special_section_klp_reloc() rejects it at build time.
test-jump-label-module-key covers that for a global key. A file-local one takes a different route to the same check: the compiler references a static through its section symbol plus an addend, so the key has to be resolved from the section before it can be recognised as STT_OBJECT at all. Until commit f9fb44b0ecef ("objtool/klp: Fix detection of corrupt static branch/call entries") it was not, and the reference was silently emitted.
Give the fixture a STATIC_KEY knob and cover it. The test checks that the input really does reference the key through its section, since without that it is only a second copy of the existing test.
Verified by reverting commit f9fb44b0ecef ("objtool/klp: Fix detection of corrupt static branch/call entries"): klp diff accepts the input and the test fails, under both gcc and clang.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-44-song@kernel.org
show more ...
|
| 2bbf68f4 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for symbols whose linkage the patch changes
A patch can move a symbol between static and global without renaming it: dropping "static" from a helper so something else can call
objtool/klp: Add test for symbols whose linkage the patch changes
A patch can move a symbol between static and global without renaming it: dropping "static" from a helper so something else can call it, or adding it to one that is no longer shared. Correlation keys off more than the name, so a symbol whose binding moved has to still pair with itself.
Failing to is not a build failure. The symbol looks new, and a new data symbol is either rejected or cloned as a second copy -- at which point the patched code updates its own private variable while the rest of the kernel keeps reading the original.
The test covers both directions in one fixture, a function going global and a variable going static, and asserts the outcome rather than the absence of a warning: each symbol resolves back to the kernel's copy through a klp symbol, and neither is cloned into the patch.
An earlier version asserted only that no "no correlation" or "changed data" message appeared, and passed with correlation deliberately broken. What the messages say and what the patch contains are not the same question.
Verified to fail with correlation made to require matching symbol bindings.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-43-song@kernel.org
show more ...
|
| 62ef2041 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for kCFI prefix symbols and traps
Two properties, asserted separately because they fail differently:
- the __cfi_<func> prefix symbol has to be carried with the patched
objtool/klp: Add test for kCFI prefix symbols and traps
Two properties, asserted separately because they fail differently:
- the __cfi_<func> prefix symbol has to be carried with the patched function, or the function has no type identity and indirect calls to it trap; - its .kcfi_traps entry has to be extracted, or the trap is not recognised as a CFI failure and a clean report becomes an oops.
test-special-section hand-assembles a .kcfi_traps entry, which is what makes it catch commit 7df1638df97b ("objtool/klp: Fix .kcfi_traps special section extraction"). Nothing until now built real kCFI code.
This tests the behavior of commit da4326573ae8 ("objtool/klp: Fix kCFI trap handling"). Commit f7ceffd21a8a ("objtool/klp: Fix kCFI prefix finding/cloning") cannot be tested as such, its code having been rewritten by commit fe6a87e0abac ("objtool: Improve and simplify prefix symbol detection"); this guards the current implementation's behaviour instead.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-42-song@kernel.org
show more ...
|
| ce30479f | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for __bug_table, __ex_table and __mcount_loc extraction
Three special sections with no coverage. An entry that is not carried into the patch is not a build failure: the patche
objtool/klp: Add test for __bug_table, __ex_table and __mcount_loc extraction
Three special sections with no coverage. An entry that is not carried into the patch is not a build failure: the patched function simply loses its WARN_ON location, its exception fixup, or its ftrace callsite, and nobody finds out until one of them is needed.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-41-song@kernel.org
show more ...
|
| 2e49f7a8 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for static locals which must not be correlated
Most static locals have to be correlated so the patched code keeps using the running kernel's copy. Two kinds must not: anything
objtool/klp: Add test for static locals which must not be correlated
Most static locals have to be correlated so the patched code keeps using the running kernel's copy. Two kinds must not: anything in .data..once, the flag behind WARN_ONCE and friends, and the well-known names the kernel generates for per-instance things (__warned, __key, __func__).
Sharing a .data..once flag means a patch inherits "already warned" from before it was applied, and the warning it was meant to surface never fires.
The fixture deliberately does not name its .data..once variable __warned: the name rule would then catch it and the section rule would go untested. gcc spells these <var>.<id> and Clang <func>.<var>, so both are covered.
This tests the behavior of commit ff529864e738 ("objtool/klp: Fix .data..once static local non-correlation") and commit 84c304a534b8 ("objtool/klp: Fix is_uncorrelated_static_local() for Clang").
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-40-song@kernel.org
show more ...
|
| 1a50e18b | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for sympos resolved against a linked vmlinux
vmlinux is not like a module: the final link reorders sub-sections, so a symbol's position has to come from the linked image rather
objtool/klp: Add test for sympos resolved against a linked vmlinux
vmlinux is not like a module: the final link reorders sub-sections, so a symbol's position has to come from the linked image rather than from symbol table order. klp diff bridges that with .klp.symid, and looks for it only when the object it was handed is called vmlinux.o with a vmlinux beside it.
This was assigned to an end-to-end test on the assumption that it needs a real kernel build. It needs "ld -r" and "ld -e 0", and takes a fraction of a second.
The fixture places the static appearing first in the symbol table at the higher address, and the link passes --sort-section=name to force the reordering the kernel's linker script performs. Without that the two ways of computing sympos agree, and a first version passed with the vmlinux path disabled.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-39-song@kernel.org
show more ...
|
| 638df22c | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for sympos in module objects
klp-sympos.c had no coverage at all. sympos disambiguates same-named symbols for livepatch, counting from 1, with 0 meaning the name is unique. Re
objtool/klp: Add test for sympos in module objects
klp-sympos.c had no coverage at all. sympos disambiguates same-named symbols for livepatch, counting from 1, with 0 meaning the name is unique. Resolving to the wrong one is not a load failure -- it is a patch quietly wired to the wrong object.
Covers the module path, where the position is a count in symbol table order and klp diff can work it out from the object alone.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-38-song@kernel.org
show more ...
|
| f55eae8f | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for position-independent checksums
A function that only moves has not changed, and its checksum must not move with it. Otherwise every patch reports as changed everything that
objtool/klp: Add test for position-independent checksums
A function that only moves has not changed, and its checksum must not move with it. Otherwise every patch reports as changed everything that shifted because something ahead of it grew.
The fixture is built with -fno-function-sections, overriding the harness default: with per-function sections every function sits at offset 0 of its own section and nothing ever moves, so the test would prove nothing. It also calls across to another function rather than looping within itself -- a loop branch keeps the same displacement wherever the function goes, so it is not position-dependent to begin with.
This tests the behavior of commit cca84cb12908 ("objtool/klp: Fix position-dependent checksums for non-relocated jumps/calls").
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-37-song@kernel.org
show more ...
|
| a5f001a4 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for recorded checksum values
Whether klp diff treats a function as changed is decided by its checksum, and until now nothing looked at one. A test asserting only that the righ
objtool/klp: Add test for recorded checksum values
Whether klp diff treats a function as changed is decided by its checksum, and until now nothing looked at one. A test asserting only that the right functions were cloned cannot tell a correct checksum from one that happens to differ.
Asserts both directions -- the changed function's checksum moves, the untouched one's does not -- and that checksumming identical input twice gives the same answer, since otherwise every rebuild reports spurious changes.
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-36-song@kernel.org
show more ...
|
| dff07c58 | 16-Sep-2026 |
Song Liu <song@kernel.org> |
objtool/klp: Add test for empty x86 alternative replacements
ALTERNATIVE_2("orig", "repl", ft1, "", ft2) produces a second entry whose replacement is empty. Its replacement offset still carries a r
objtool/klp: Add test for empty x86 alternative replacements
ALTERNATIVE_2("orig", "repl", ft1, "", ft2) produces a second entry whose replacement is empty. Its replacement offset still carries a relocation, but the label it points at is the end of the previous replacement -- which is also where the next one begins. The value is meaningless and only ever used with a length of zero, so cloning must not follow it.
The first version of this fixture passed with the fix reverted, because the empty entry pointed at its own end label rather than at the neighbour's replacement. It has to reach into another function's replacement to distinguish the behaviour.
This tests the behavior of commit 636f230ce21e ("objtool/klp: Ignore replacement offset of empty x86 alternatives").
Assisted-by: Claude:claude-opus-4 Based-on-test-by: Joe Lawrence <joe.lawrence@redhat.com> Assisted-by: Claude:claude-opus-5 Signed-off-by: Song Liu <song@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20260916184351.2720310-35-song@kernel.org
show more ...
|