All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: joe.lawrence@redhat.com, jpoimboe@kernel.org, mbenes@suse.cz,
	jikos@kernel.org, pmladek@suse.com, song@kernel.org,
	"Yafang Shao" <laoar.shao@gmail.com>
Cc: live-patching@vger.kernel.org
Subject: Re: [PATCH 2/2] livepatch: Fix UAF of unregistered patch kobjects
Date: Thu, 13 Aug 2026 03:16:11 +0000	[thread overview]
Message-ID: <20260813031611.A4EAD1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260813030408.9761-3-laoar.shao@gmail.com>

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

New issues:
- [Critical] The newly added release signaling logic introduces a direct Use-After-Free when processing dynamically allocated objects and NOP functions in the kobject release paths.

Pre-existing issues:
- [High] The patch fails to fully resolve the original delayed kobject release Use-After-Free if partial initialization fails after the patch kobject has been added, leaving child kobjects un-added.
--

--- Patch [2]: [PATCH 2/2] livepatch: Fix UAF of unregistered patch kobjects ---
commit ac38837d810b471eed544191021bf254f8b9e585
Author: Yafang Shao <laoar.shao@gmail.com>

livepatch: Fix UAF of unregistered patch kobjects

When klp_enable_patch() fails after klp_init_patch_early() has run,
delayed kobject releases can cause use-after-free bugs when the module
is unloaded. This patch tracks pending kobject releases and waits for
them before completion.

Link: https://lore.kernel.org/all/20260809094046.50ED31F000E9@smtp.kernel.org/

> diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
> index 28d15ba58a26d..e07b026feeb99 100644
> --- a/kernel/livepatch/core.c
> +++ b/kernel/livepatch/core.c

[ ... ]

> @@ -652,6 +653,14 @@ static void klp_kobj_release_object(struct kobject *kobj)
>  
>  	if (obj->dynamic)
>  		klp_free_object_dynamic(obj);
> +
> +	/*
> +	 * The object kobject was initialized but never added to sysfs.
> +	 * Signal the release to the owning patch.
> +	 */
> +	if (!obj->patch->kobj_added &&
> +	    atomic_dec_and_test(&obj->patch->kobj_pending))
> +		complete(&obj->patch->finish);
>  }

[Severity: Critical]
Does this dereference the freed obj pointer?

If obj->dynamic is true, klp_free_object_dynamic(obj) is called, which
frees the object structure. Immediately after this intentional free, the
newly added logic dereferences the freed pointer by evaluating
!obj->patch->kobj_added.

> @@ -668,6 +677,13 @@ static void klp_kobj_release_func(struct kobject *kobj)
>  
>  	if (func->nop)
>  		klp_free_func_nop(func);
> +	/*
> +	 * The function kobject was initialized but never added to sysfs.
> +	 * Signal the release to the owning patch.
> +	 */
> +	if (!func->obj->patch->kobj_added &&
> +	    atomic_dec_and_test(&func->obj->patch->kobj_pending))
> +		complete(&func->obj->patch->finish);
>  }

[Severity: Critical]
Similarly here, does this access func after it has been freed?

If func->nop is true, klp_free_func_nop(func) frees the function,
but the new check immediately dereferences func->obj->patch->kobj_added.

[ ... ]

> @@ -737,9 +753,29 @@ static void klp_free_objects_dynamic(struct klp_patch *patch)
>   */
>  static void klp_free_patch_start(struct klp_patch *patch)
>  {
> +	struct klp_object *obj;
> +	struct klp_func *func;
> +
>  	if (!list_empty(&patch->list))
>  		list_del(&patch->list);
>  
> +	if (!patch->kobj_added) {

[Severity: High]
This is a pre-existing issue, but does this check leave child kobjects
unprotected if partial initialization fails after the patch kobject has
been added?

If klp_init_patch() successfully adds the patch kobject, it sets
patch->kobj_added = true. If a subsequent operation like klp_add_nops()
or klp_init_object() fails, klp_free_patch_start() is called on the
error path.

Because patch->kobj_added is true, this check is bypassed and
patch->kobj_pending tracking is not initialized. However, child kobjects
that were initialized early but not yet added to sysfs do not hold a
reference to patch->kobj. Thus, patch->kobj will be released
independently, unblocking patch->finish, and allowing the livepatch
module to be unloaded while un-added child kobjects may still trigger
their delayed releases and access freed module memory.

> +		/*
> +		 * The kobjects were only initialized and never added to
> +		 * sysfs. Count them so that klp_free_patch_finish() can
> +		 * wait for all their releases before the patch module is
> +		 * unloaded. Without this, a delayed kobject release
> +		 * (CONFIG_DEBUG_KOBJECT_RELEASE) could access the freed
> +		 * module memory.
> +		 */
> +		atomic_set(&patch->kobj_pending, 1); /* the patch kobject */
> +		klp_for_each_object(patch, obj) {
> +			atomic_inc(&patch->kobj_pending);
> +			klp_for_each_func(obj, func)
> +				atomic_inc(&patch->kobj_pending);
> +		}
> +	}
> +
>  	klp_free_objects(patch);
>  }

[ ... ]

> @@ -987,6 +1027,7 @@ static int klp_init_patch(struct klp_patch *patch)
>  	ret = kobject_add(&patch->kobj, klp_root_kobj, "%s", patch->mod->name);
>  	if (ret)
>  		return ret;
> +	patch->kobj_added = true;
>  
>  	if (patch->replace) {
>  		ret = klp_add_nops(patch);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260813030408.9761-1-laoar.shao@gmail.com?part=2

  reply	other threads:[~2026-08-13  3:16 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-13  3:04 [PATCH 0/2] livepatch: Fix several bugs found during replace set implementation Yafang Shao
2026-08-13  3:04 ` [PATCH 1/2] livepatch: Fix wrong index in funcs cleanup error path Yafang Shao
2026-08-14 20:36   ` Song Liu
2026-08-16  2:45     ` Yafang Shao
2026-08-13  3:04 ` [PATCH 2/2] livepatch: Fix UAF of unregistered patch kobjects Yafang Shao
2026-08-13  3:16   ` sashiko-bot [this message]
2026-08-13  3:58     ` Yafang Shao

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=20260813031611.A4EAD1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=jikos@kernel.org \
    --cc=joe.lawrence@redhat.com \
    --cc=jpoimboe@kernel.org \
    --cc=laoar.shao@gmail.com \
    --cc=live-patching@vger.kernel.org \
    --cc=mbenes@suse.cz \
    --cc=pmladek@suse.com \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=song@kernel.org \
    /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.