From: sashiko-bot@kernel.org
To: "Hui Zhu" <hui.zhu@linux.dev>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH v3] bpf: Fix UAF in bpf_trampoline_multi_attach_free on update failure
Date: Mon, 10 Aug 2026 02:39:26 +0000 [thread overview]
Message-ID: <20260810023927.659F91F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260810022304.211544-1-hui.zhu@linux.dev>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [Critical] Ignoring errors during BPF link detachment leads to a Use-After-Free of the `bpf_prog` when ftrace or trampoline updates fail.
- [Critical] The patch is incomplete: it fixes a UAF of the trampoline image when `bpf_trampoline_update()` fails, but leaves an identical UAF if ftrace direct modifications fail during multi-detach.
--
--- Patch [1]: [PATCH v3] bpf: Fix UAF in bpf_trampoline_multi_attach_free on update failure ---
commit 569677dafd5f99230e4a9c93925fbe240c10aadd
Author: Hui Zhu <zhuhui@kylinos.cn>
bpf: Fix UAF in bpf_trampoline_multi_attach_free on update failure
This patch modifies bpf_trampoline_multi_attach_free() to only free
old_image if it differs from cur_image, aiming to prevent a use-after-free
when bpf_trampoline_update() fails. It also changes
bpf_trampoline_multi_detach() to return void.
> diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
> index e07af35ed0402..b76d162517e36 100644
> --- a/kernel/bpf/trampoline.c
> +++ b/kernel/bpf/trampoline.c
[ ... ]
> @@ -1632,7 +1632,18 @@ static void bpf_trampoline_multi_attach_init(struct bpf_trampoline *tr)
>
> static void bpf_trampoline_multi_attach_free(struct bpf_trampoline *tr)
> {
> - if (tr->multi_attach.old_image)
> + /*
> + * Only free old_image if it is no longer the active image.
> + * When bpf_trampoline_update() fails before modify_fentry_multi()/
> + * unregister_fentry_multi() is called, cur_image is unchanged
> + * (cur_image == old_image) and ftrace still points to it. Freeing
> + * it would cause a UAF when ftrace calls into the freed memory.
> + * On success, cur_image is either a new image or NULL, so
> + * old_image != cur_image correctly identifies a stale image that
> + * is safe to free.
> + */
> + if (tr->multi_attach.old_image &&
> + tr->multi_attach.old_image != tr->cur_image)
> bpf_tramp_image_put(tr->multi_attach.old_image);
[Severity: Critical]
This is a pre-existing issue, but does this logic leave another window for
a use-after-free if ftrace modifications fail?
During bpf_trampoline_multi_detach(), if __bpf_trampoline_unlink_prog()
succeeds, it updates tr->cur_image to a new image or NULL. If a subsequent
call to update ftrace fails (for example, a memory allocation failure inside
update_ftrace_direct_del()), ftrace is not updated and continues to point
to old_image.
Because tr->cur_image was updated, the condition here evaluates to true.
This appears to erroneously free old_image while ftrace is still using it,
potentially causing a crash when the traced function is executed.
[ ... ]
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index 891897f8a1b35..29260951aa871 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -3687,7 +3687,7 @@ static void bpf_tracing_multi_link_release(struct bpf_link *link)
> struct bpf_tracing_multi_link *tr_link =
> container_of(link, struct bpf_tracing_multi_link, link);
>
> - WARN_ON_ONCE(bpf_trampoline_multi_detach(link->prog, tr_link));
> + bpf_trampoline_multi_detach(link->prog, tr_link);
> }
[Severity: Critical]
This is a pre-existing issue, but by treating detachment as always
successful here, do we risk a use-after-free of the bpf_prog itself?
If __bpf_trampoline_unlink_prog() fails inside bpf_trampoline_multi_detach(),
the error is logged with a warning, but execution continues. In this scenario,
the active trampoline image still contains a jump to the BPF program.
Since bpf_tracing_multi_link_release() proceeds to destroy the bpf_link
and drops the final reference to the bpf_prog, the program memory is freed.
However, the ftrace hook remains active and points to the freed bpf_prog,
which can trigger a crash when the traced function is called.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260810022304.211544-1-hui.zhu@linux.dev?part=1
next prev parent reply other threads:[~2026-08-10 2:39 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-10 2:23 [PATCH v3] bpf: Fix UAF in bpf_trampoline_multi_attach_free on update failure Hui Zhu
2026-08-10 2:39 ` sashiko-bot [this message]
2026-08-10 3:36 ` bot+bpf-ci
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=20260810023927.659F91F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=hui.zhu@linux.dev \
--cc=sashiko-reviews@lists.linux.dev \
/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