Skip to content

create-diff-object: register patchable child functions - #1526

Open
benjamindonnachie wants to merge 1 commit into
dynup:masterfrom
benjamindonnachie:fix-patchable-child-registration-upstream
Open

benjamindonnachie wants to merge 1 commit into
dynup:masterfrom
benjamindonnachie:fix-patchable-child-registration-upstream

Conversation

@benjamindonnachie

Copy link
Copy Markdown

Summary

  • register changed compiler-generated child functions when they have their own profiling entry
  • continue carrying children without a profiling entry through their changed parent
  • avoid registering a child separately when a changed ancestor already carries its replacement code

Problem

GCC split snd_timer_interrupt() into an unchanged wrapper and a changed
snd_timer_interrupt.part.0. The child had its own __fentry__, so
kpatch_compare_sections() correctly avoided promoting the unchanged parent.

Later, kpatch_create_patches_sections() unconditionally skipped every symbol
with sym->parent. The resulting livepatch module contained the changed child
text and its KLP relocations, but no .kpatch.funcs registration record. The
module loaded successfully while the changed execution path remained unpatched.

Validation

  • make -C kpatch-build -j4 (with -Werror): pass
  • make -C test/unit ARCHES=x86_64: pass
  • full EL9 exact-kernel build for 5.14.0-687.48.1.el9_8.x86_64: pass
  • module metadata increased from 26 to 27 function records and included snd_timer_interrupt.part.0
  • privileged runtime load: enabled=1, transition=0
  • livepatch sysfs registered both snd_timer_interrupt.part.0,1 and snd_timer_close_locked,1

The failure was discovered while auditing a cumulative security livepatch: the
source/CVE manifest claimed coverage and the module loaded normally, but sysfs
showed the missing child-function registration.

Closes #1525

Compiler-generated child functions such as *.part.* can have their own profiling call.  In that case kpatch_compare_sections() deliberately leaves an unchanged parent unmodified because the child can be patched independently.

However, kpatch_create_patches_sections() unconditionally skips every symbol with a parent.  The replacement child text and relocations are retained in the module, but no .kpatch.funcs record is emitted, so the kernel never registers or redirects the changed function.

Use one predicate for change reporting and patch metadata generation.  Register a changed child when it has its own profiling entry and no changed ancestor already carries its replacement code.  Continue excluding unpatchable children and children covered by a changed ancestor.

Fixes: af1fe26 ("create-diff-object: Avoid unnecessary parent symbol inclusion")

Signed-off-by: Benjamin Donnachie <benjamin@py-soft.co.uk>

Co-authored-by: OpenAI Codex <codex@openai.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

create-diff-object can omit patchable changed child functions

1 participant