From: sashiko-bot@kernel.org
To: "Chengfeng Ye" <nicoyip.dev@gmail.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH bpf v4] bpf, sockmap: Fix cork use-after-free in tcp_bpf_sendmsg()
Date: Fri, 24 Jul 2026 10:56:06 +0000 [thread overview]
Message-ID: <20260724105606.BE1851F00A3D@smtp.kernel.org> (raw)
In-Reply-To: <20260724103856.3399001-1-nicoyip.dev@gmail.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] Concurrent sends on the same socket with an active redirect verdict cause a Use-After-Free on the target redirect socket (`sk_redir`).
- [High] `memcpy` is called with identical source and destination pointers when appending to an existing cork.
- [High] A failed allocation of `psock->cork` leaves `psock->cork_bytes` greater than zero, leading to a memory leak of the stack-allocated `tmp` message and silent data loss on subsequent `sendmsg()` calls.
--
--- Patch [1]: [PATCH bpf v4] bpf, sockmap: Fix cork use-after-free in tcp_bpf_sendmsg() ---
commit df6d10c569d9a8f6bacb9c15795f057eb688c1ef
Author: Chengfeng Ye <nicoyip.dev@gmail.com>
Subject: bpf, sockmap: Fix cork use-after-free in tcp_bpf_sendmsg()
tcp_bpf_sendmsg() keeps msg_tx across sk_stream_wait_memory(), which drops
and reacquires the socket lock. This patch fixes a use-after-free caused
by an unsafe comparison between msg_tx and psock->cork, resolving it by
checking directly against the stack-local tmp message.
Link: https://lore.kernel.org/bpf/87fr18lmzo.fsf%40cloudflare.com/
Link: https://lore.kernel.org/netdev/20260719161630.2901208-1-nicoyip.dev%40gmail.com/
> diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
> index 8e905b50deadb..a30475afb6f89 100644
> --- a/net/ipv4/tcp_bpf.c
> +++ b/net/ipv4/tcp_bpf.c
[ ... ]
[Severity: High]
This isn't a bug introduced by this patch, but could this leak the tmp
message and cause silent data loss if an earlier cork allocation fails?
In tcp_bpf_send_verdict(), psock->cork_bytes is updated before allocating
psock->cork:
net/ipv4/tcp_bpf.c:tcp_bpf_send_verdict() {
...
if (msg->cork_bytes &&
msg->cork_bytes > msg->sg.size && !enospc) {
psock->cork_bytes = msg->cork_bytes - msg->sg.size;
if (!psock->cork) {
psock->cork = kzalloc_obj(*psock->cork, ...);
if (!psock->cork) {
sk_msg_free(sk, msg);
*copied = 0;
return -ENOMEM;
}
...
}
If the allocation fails, psock->cork_bytes remains greater than zero.
Then, on a subsequent sendmsg(), tcp_bpf_sendmsg() populates the stack-local
tmp message, sees the non-zero psock->cork_bytes, and jumps directly to
out_err:
net/ipv4/tcp_bpf.c:tcp_bpf_sendmsg() {
...
if (psock->cork_bytes) {
if (size > psock->cork_bytes)
psock->cork_bytes = 0;
else
psock->cork_bytes -= size;
if (psock->cork_bytes && !enospc)
goto out_err;
...
}
Because it bypasses the error path cleanup below, doesn't this permanently
leak the tmp message's page fragments and silently drop the data?
[Severity: High]
This is a pre-existing issue, but does appending to a cork execute undefined
behavior by calling memcpy() with identical pointers?
In tcp_bpf_sendmsg(), if psock->cork is already allocated, msg_tx is set to
point to it and passed to tcp_bpf_send_verdict() as the msg argument. If the
BPF program requests further corking, the code does this:
net/ipv4/tcp_bpf.c:tcp_bpf_send_verdict() {
...
if (!psock->cork) {
psock->cork = kzalloc_obj(*psock->cork, ...);
...
}
memcpy(psock->cork, msg, sizeof(*msg));
return 0;
...
}
Since msg is exactly psock->cork here, does this result in a memcpy() with
identical source and destination pointers, potentially causing a kernel
panic with FORTIFY_SOURCE or KASAN?
[Severity: High]
This is a pre-existing issue, but is there a use-after-free on sk_redir
when multiple threads send on the same socket concurrently?
When a BPF program returns __SK_REDIRECT with apply_bytes > 0,
sk_psock_msg_verdict() takes a single reference on the target socket via
sock_hold(psock->sk_redir).
If multiple threads process the remaining apply_bytes for this socket, they
all read psock->sk_redir and release the socket lock to call
tcp_bpf_sendmsg_redir():
net/ipv4/tcp_bpf.c:tcp_bpf_send_verdict() {
...
case __SK_REDIRECT:
redir_ingress = psock->redir_ingress;
sk_redir = psock->sk_redir;
sk_msg_apply_bytes(psock, tosend);
if (!psock->apply_bytes) {
/* Clean up before releasing the sock lock. */
eval = psock->eval;
psock->eval = __SK_NONE;
psock->sk_redir = NULL;
}
...
release_sock(sk);
origsize = msg->sg.size;
ret = tcp_bpf_sendmsg_redir(sk_redir, redir_ingress, ...);
sent = origsize - msg->sg.size;
if (eval == __SK_REDIRECT)
sock_put(sk_redir);
...
}
The thread that exhausts apply_bytes clears psock->sk_redir and calls
sock_put(sk_redir) to drop the single reference. Since it doesn't wait for
other concurrent threads to finish, could the target socket be freed while
they are still executing tcp_bpf_sendmsg_redir(sk_redir)?
[ ... ]
> @@ -604,7 +604,7 @@ static int tcp_bpf_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
> wait_for_memory:
> err = sk_stream_wait_memory(sk, &timeo);
> if (err) {
> - if (msg_tx && msg_tx != psock->cork)
> + if (msg_tx == &tmp)
> sk_msg_free(sk, msg_tx);
> goto out_err;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260724103856.3399001-1-nicoyip.dev@gmail.com?part=1
next prev parent reply other threads:[~2026-07-24 10:56 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-19 16:16 [PATCH] bpf, sockmap: Fix cork use-after-free in tcp_bpf_sendmsg() Chengfeng Ye
2026-07-20 16:17 ` sashiko-bot
2026-07-20 20:12 ` Emil Tsalapatis
2026-07-23 15:41 ` Chengfeng Ye
2026-07-23 15:34 ` [PATCH v2] bpf, sockmap: Fix cork ownership " Chengfeng Ye
2026-07-23 15:49 ` sashiko-bot
2026-07-23 16:26 ` [PATCH v3] " Chengfeng Ye
2026-07-23 16:39 ` sashiko-bot
2026-07-23 17:00 ` Jakub Kicinski
2026-07-24 9:40 ` Jakub Sitnicki
2026-07-24 10:02 ` Chengfeng Ye
2026-07-24 10:07 ` Jakub Sitnicki
2026-07-24 10:38 ` [PATCH bpf v4] bpf, sockmap: Fix cork use-after-free " Chengfeng Ye
2026-07-24 10:48 ` Jakub Sitnicki
2026-07-24 10:56 ` sashiko-bot [this message]
2026-07-24 10:43 ` [PATCH v3] bpf, sockmap: Fix cork ownership " Chengfeng Ye
2026-07-23 17:44 ` 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=20260724105606.BE1851F00A3D@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=nicoyip.dev@gmail.com \
--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