The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: mbenes@suse.cz, jikos@kernel.org, "Harry Hsu" <x90613@gmail.com>,
	pmladek@suse.com, jpoimboe@kernel.org
Cc: live-patching@vger.kernel.org, linux-kernel@vger.kernel.org,
	joe.lawrence@redhat.com
Subject: Re: [PATCH] livepatch: Fix stack check for aliased old_func
Date: Wed, 12 Aug 2026 15:07:28 +0000	[thread overview]
Message-ID: <20260812150728.B70B41F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260812140232.48079-1-x90613@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [High] klp_ftrace_handler() incorrectly executes newly patched code for unpatched tasks when multiple aliased functions exist in the same transition patch.
- [High] Premature freeing of dynamically allocated NOP functions without RCU synchronization leads to a Use-After-Free in klp_ftrace_handler().
- [High] Concurrent module loading or unloading during a livepatch transition causes list corruption and Use-After-Free due to lockless klp_ops traversal.
--

--- Patch [1]: [PATCH] livepatch: Fix stack check for aliased old_func ---
commit 3438e93da695fdf6d92c99235da90b29e8a2a08f
Author: Harry Hsu <x90613@gmail.com>

livepatch: Fix stack check for aliased old_func

This patch fixes an out-of-bounds read and an infinite -EAGAIN loop in
klp_check_stack_func() when aliased functions share a single func_stack.
It addresses the issue by testing the function's position in the stack
rather than relying on list_is_singular().

> diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
> index 2351a19ac2a9e..8d6e3a58101fc 100644
> --- a/kernel/livepatch/transition.c
> +++ b/kernel/livepatch/transition.c
> @@ -223,7 +223,7 @@ static int klp_check_stack_func(struct klp_func *func, unsigned long *entries,
>  		 */
>  		ops = klp_find_ops(func->old_func);

[Severity: High]
This is a pre-existing issue and was not introduced by the patch under review,
but does klp_find_ops() traverse the global klp_ops list safely here?

Since klp_check_stack_func() can be called during a context switch, it executes
without klp_mutex protection. If a patched module is concurrently unloaded,
klp_module_going() acquires klp_mutex and calls klp_unpatch_func(), which
removes the ops from the list and frees it:

kernel/livepatch/patch.c:klp_unpatch_func() {
        ...
        list_del_rcu(&func->stack_node);
        list_del(&ops->node);
        kfree(ops);
        ...
}

Could this concurrent module unloading race with the lockless traversal in
klp_find_ops() and lead to a use-after-free or list corruption?

>  
> -		if (list_is_singular(&ops->func_stack)) {
> +		if (list_is_last(&func->stack_node, &ops->func_stack)) {

[Severity: High]
This is a pre-existing issue and was not introduced by the patch under review,
but does the same list_is_singular() assumption cause a use-after-free in
klp_unpatch_func()?

When a replacement livepatch overrides only one of several aliased functions
from an older patch, a NOP function is dynamically allocated for the
un-overridden alias. When the transition finishes, klp_discard_nops() triggers
unpatching and immediate freeing of the NOP functions:

kernel/livepatch/core.c:klp_discard_nops() {
        klp_unpatch_objects_dynamic(klp_transition_patch);
        klp_free_objects_dynamic(klp_transition_patch);
}

Since the stack also contains the overridden real function, the check for
list_is_singular() in klp_unpatch_func() evaluates to false, which bypasses
unregister_ftrace_function() and its associated ftrace_sync:

kernel/livepatch/patch.c:klp_unpatch_func() {
        ...
        if (list_is_singular(&ops->func_stack)) {
                /* ... */
        } else {
                list_del_rcu(&func->stack_node);
        }
        ...
}

The NOP is then immediately freed by kfree(). If klp_ftrace_handler() executes
concurrently on another CPU, might it access the freed NOP object?

>  			/* original function */
>  			func_addr = (unsigned long)func->old_func;
>  			func_size = func->old_size;


While reviewing the alias handling, I noticed one more pre-existing issue:

[Severity: High]
This is a pre-existing issue and was not introduced by the patch under review,
but does klp_ftrace_handler() correctly handle unpatched tasks when multiple
aliased functions exist in the same transition patch?

When an unpatched task invokes the intercepted function, klp_ftrace_handler()
observes that the patch is in transition and advances exactly once:

kernel/livepatch/patch.c:klp_ftrace_handler() {
        ...
        if (patch_state == KLP_TRANSITION_UNPATCHED) {
                /*
                 * Use the previously patched version of the function.
                 * If no previous patches exist, continue with the
                 * original function.
                 */
                func = list_entry_rcu(func->stack_node.next,
                                      struct klp_func, stack_node);
        ...
}

If multiple aliases are placed on the same ops->func_stack by the same patch,
won't the next entry just be another alias that is also in transition? Can this
cause the handler to mistakenly execute newly patched code for unpatched tasks?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260812140232.48079-1-x90613@gmail.com?part=1

      reply	other threads:[~2026-08-12 15:07 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-12 14:02 [PATCH] livepatch: Fix stack check for aliased old_func Harry Hsu
2026-08-12 15:07 ` sashiko-bot [this message]

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=20260812150728.B70B41F00A3A@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=jikos@kernel.org \
    --cc=joe.lawrence@redhat.com \
    --cc=jpoimboe@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=mbenes@suse.cz \
    --cc=pmladek@suse.com \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=x90613@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox