public inbox for bpf@vger.kernel.org
 help / color / mirror / Atom feed
From: Martin KaFai Lau <martin.lau@linux.dev>
To: xulang <xulang@uniontech.com>
Cc: ast@kernel.org, bpf@vger.kernel.org, daniel@iogearbox.net,
	dddddd@hust.edu.cn, dzm91@hust.edu.cn,
	hust-os-kernel-patches@googlegroups.com, kaiyanm@hust.edu.cn,
	sdf@fomichev.me
Subject: Re: [PATCH] bpf: fix: Race condition in bpf_trampoline_unlink_cgroup_shim
Date: Thu, 12 Feb 2026 11:51:14 -0800	[thread overview]
Message-ID: <64e56f03-bc93-46c1-8d5e-fa9720821620@linux.dev> (raw)
In-Reply-To: <68AC3CE38AB1BD07+20260206071357.4075301-1-xulang@uniontech.com>



On 2/5/26 11:13 PM, xulang wrote:
> Based on Martin KaFai Lau's suggestions, I have created a simple patch.

Thanks for the patch.

> 
> The root cause of this bug is that when `bpf_link_put` reduces the
> refcount of `shim_link->link.link` to zero, the resource is considered
> released but may still be referenced via `tr->progs_hlist` in
> `cgroup_shim_find`. The actual cleanup of `tr->progs_hlist` in
> `bpf_shim_tramp_link_release` is deferred. During this window, another
> process can cause a use-after-free via `bpf_trampoline_link_cgroup_shim`.
> 
> To fix this:
> 1. Add an atomic non-zero check in `bpf_trampoline_link_cgroup_shim`.
>     Only increment the refcount if it is not already zero.

This makes sense.

> 2. Guard the freeing of `shim_link` with `tr->mutex` to prevent release
>     while the mutex is held.

I am not sure about this one (details below).

> 
> Testing:
> I used a non-rigorous method to verify the fix by adding a delay in
> `bpf_link_put` to make the bug easier to trigger:
> 
> void bpf_link_put(struct bpf_link *link)
> {
>          if (!atomic64_dec_and_test(&link->refcnt))
>                  return;
> +       msleep(100);
>          INIT_WORK(&link->work, bpf_link_put_deferred);
>          schedule_work(&link->work);
> }
> 
> Before the patch, running a PoC easily reproduced the crash (often within
> dozens of iterations) with a call trace similar to KaiyanM's report.
> After the patch, the bug no longer occurs even after millions of
> iterations.
> 
> Signed-off-by: xulang <xulang@uniontech.com>
> ---
>   kernel/bpf/trampoline.c | 14 ++++++++++----
>   1 file changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
> index 976d89011b15..c16a53cca5e0 100644
> --- a/kernel/bpf/trampoline.c
> +++ b/kernel/bpf/trampoline.c
> @@ -702,15 +702,23 @@ static void bpf_shim_tramp_link_release(struct bpf_link *link)
>   		return;
>   
>   	WARN_ON_ONCE(bpf_trampoline_unlink_prog(&shim_link->link, shim_link->trampoline, NULL));

bpf_trampoline_unlink_prog() will hold (/wait) for tr->mutex before 
unlinking from tr. The link's refcnt is already 0 here.


> -	bpf_trampoline_put(shim_link->trampoline);
>   }
>   
>   static void bpf_shim_tramp_link_dealloc(struct bpf_link *link)
>   {
>   	struct bpf_shim_tramp_link *shim_link =
>   		container_of(link, struct bpf_shim_tramp_link, link.link);
> +	struct bpf_trampoline *tr = shim_link->trampoline;
>   
> +	if (!tr) {
> +		kfree(shim_link);
> +		return;
> +	}
> +
> +	mutex_lock(&tr->mutex);

The link_release is done before the link_dealloc. Why it needs to hold 
(/wait) for the tr->mutex again?

>   	kfree(shim_link);
> +	mutex_unlock(&tr->mutex);
> +	bpf_trampoline_put(tr);
>   }
>   
>   static const struct bpf_link_ops bpf_shim_tramp_link_lops = {
> @@ -800,10 +808,8 @@ int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog,
>   	mutex_lock(&tr->mutex);
>   
>   	shim_link = cgroup_shim_find(tr, bpf_func);
> -	if (shim_link) {
> +	if (shim_link && atomic64_inc_not_zero(&shim_link->link.link.refcnt)) {

Use bpf_link_inc_not_zero().

pw-bot: cr

>   		/* Reusing existing shim attached by the other program. */
> -		bpf_link_inc(&shim_link->link.link);
> -
>   		mutex_unlock(&tr->mutex);
>   		bpf_trampoline_put(tr); /* bpf_trampoline_get above */
>   		return 0;


  parent reply	other threads:[~2026-02-12 19:51 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-25 11:14 bpf: Race condition in bpf_trampoline_unlink_cgroup_shim during concurrent cgroup LSM link release 梅开彦
2025-12-01 20:21 ` Martin KaFai Lau
2025-12-02  4:48   ` 梅开彦
2026-02-06  7:13   ` [PATCH] bpf: fix: Race condition in bpf_trampoline_unlink_cgroup_shim xulang
2026-02-06  7:50     ` bot+bpf-ci
2026-02-12 19:51     ` Martin KaFai Lau [this message]
2026-02-24  9:42       ` xulang
2026-02-25  6:54       ` [PATCH v2] " xulang
2026-02-25  7:38         ` bot+bpf-ci
2026-02-27 20:33           ` Martin KaFai Lau
2026-02-28  2:24             ` [PATCH bpf v3] " xulang
2026-02-28  3:04               ` bot+bpf-ci
2026-03-03  2:39                 ` Martin KaFai Lau
2026-03-03  8:36                   ` [PATCH bpf v4] " xulang
2026-03-03  9:28                     ` bot+bpf-ci
2026-03-03  9:52                       ` [PATCH bpf v5] bpf: fix: Race condition in bpf_trampoline_link_cgroup_shim xulang
2026-03-03 23:30                         ` patchwork-bot+netdevbpf
2026-03-03 23:30                     ` [PATCH bpf v4] bpf: fix: Race condition in bpf_trampoline_unlink_cgroup_shim patchwork-bot+netdevbpf
2026-03-03 23:46                       ` Martin KaFai Lau

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=64e56f03-bc93-46c1-8d5e-fa9720821620@linux.dev \
    --to=martin.lau@linux.dev \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=dddddd@hust.edu.cn \
    --cc=dzm91@hust.edu.cn \
    --cc=hust-os-kernel-patches@googlegroups.com \
    --cc=kaiyanm@hust.edu.cn \
    --cc=sdf@fomichev.me \
    --cc=xulang@uniontech.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