From: Chengfeng Ye <nicoyip.dev@gmail.com>
To: Eric Dumazet <edumazet@google.com>,
Neal Cardwell <ncardwell@google.com>,
Kuniyuki Iwashima <kuniyu@google.com>,
John Fastabend <john.fastabend@gmail.com>,
Jakub Sitnicki <jakub@cloudflare.com>,
Jiayuan Chen <jiayuan.chen@linux.dev>,
"David S. Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>
Cc: netdev@vger.kernel.org, bpf@vger.kernel.org,
linux-kernel@vger.kernel.org,
Chengfeng Ye <nicoyip.dev@gmail.com>,
stable@vger.kernel.org, Emil Tsalapatis <emil@etsalapatis.com>
Subject: [PATCH v2] bpf, sockmap: Fix cork ownership in tcp_bpf_sendmsg()
Date: Thu, 23 Jul 2026 23:34:50 +0800 [thread overview]
Message-ID: <20260723153450.3224353-1-nicoyip.dev@gmail.com> (raw)
In-Reply-To: <20260719161630.2901208-1-nicoyip.dev@gmail.com>
tcp_bpf_sendmsg() keeps msg_tx across sk_stream_wait_memory(), which drops
and reacquires the socket lock. Its error path used the current value of
psock->cork to decide whether msg_tx named the stack-local temporary
message.
Two senders can therefore interleave as follows:
Thread A Thread B
msg_tx = psock->cork
sk_msg_alloc() fails
sk_stream_wait_memory()
releases the socket lock acquires the socket lock
completes the cork
psock->cork = NULL
frees the cork
reacquires the socket lock
msg_tx != psock->cork
sk_msg_free(msg_tx)
The stale cork is mistaken for the local temporary message and freed again.
KASAN reported:
BUG: KASAN: slab-use-after-free in sk_msg_free+0x49/0x50
Read of size 4 at addr ffff88810c908800 by task poc/90
Call Trace:
sk_msg_free+0x49/0x50
tcp_bpf_sendmsg+0x14f5/0x1cc0
__sys_sendto+0x32c/0x3a0
__x64_sys_sendto+0xdb/0x1b0
Allocated by task 89:
__kasan_kmalloc+0x8f/0xa0
tcp_bpf_sendmsg+0x16b3/0x1cc0
Freed by task 91:
__kasan_slab_free+0x43/0x70
kfree+0x131/0x3c0
tcp_bpf_sendmsg+0xec3/0x1cc0
The same unclear ownership also leaves several error paths inconsistent.
A failed cork allocation leaves cork_bytes armed, a subsequent temporary
message can escape without releasing its pages, iterator errors are
returned as success, and a failed redirect of a corked message discards
data while reporting it as sent. Re-evaluating an existing cork can also
copy the object onto itself.
Make temporary ownership explicit by freeing only &tmp at the common exit.
Reset cork_bytes when allocating the persistent cork fails, propagate
iterator errors, preserve redirect failures and clear the copied count
when corked data is discarded. Skip the copy when the message is already
the persistent cork.
Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
Cc: stable@vger.kernel.org
Suggested-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
---
Changes in v2:
- Address Sashiko review findings for stale cork state, iterator-error
propagation, cork self-copy, and masked redirect failures.
- Keep the original stale-cork use-after-free fix.
Sashiko: https://sashiko.dev/#/patchset/20260719161630.2901208-1-nicoyip.dev%40gmail.com
Link: https://lore.kernel.org/netdev/20260719161630.2901208-1-nicoyip.dev@gmail.com/ [v1]
net/ipv4/tcp_bpf.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
index 8e905b50dead..0594ee4013b0 100644
--- a/net/ipv4/tcp_bpf.c
+++ b/net/ipv4/tcp_bpf.c
@@ -443,12 +443,14 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
psock->cork = kzalloc_obj(*psock->cork,
GFP_ATOMIC | __GFP_NOWARN);
if (!psock->cork) {
+ psock->cork_bytes = 0;
sk_msg_free(sk, msg);
*copied = 0;
return -ENOMEM;
}
}
- memcpy(psock->cork, msg, sizeof(*msg));
+ if (psock->cork != msg)
+ memcpy(psock->cork, msg, sizeof(*msg));
return 0;
}
@@ -495,14 +497,15 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
if (unlikely(ret < 0)) {
int free = sk_msg_free(sk, msg);
- if (!cork)
+ if (cork)
+ *copied = 0;
+ else
*copied -= free;
}
if (cork) {
sk_msg_free(sk, msg);
kfree(msg);
msg = NULL;
- ret = 0;
}
break;
case __SK_DROP:
@@ -579,6 +582,7 @@ static int tcp_bpf_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
copy);
if (ret < 0) {
sk_msg_trim(sk, msg_tx, osize);
+ err = ret;
goto out_err;
}
@@ -603,13 +607,12 @@ static int tcp_bpf_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
wait_for_memory:
err = sk_stream_wait_memory(sk, &timeo);
- if (err) {
- if (msg_tx && msg_tx != psock->cork)
- sk_msg_free(sk, msg_tx);
+ if (err)
goto out_err;
- }
}
out_err:
+ if (msg_tx == &tmp)
+ sk_msg_free(sk, msg_tx);
if (err < 0)
err = sk_stream_error(sk, msg->msg_flags, err);
release_sock(sk);
--
2.43.0
next prev parent reply other threads:[~2026-07-23 15:35 UTC|newest]
Thread overview: 10+ 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 ` Chengfeng Ye [this message]
2026-07-23 15:49 ` [PATCH v2] bpf, sockmap: Fix cork ownership " 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-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=20260723153450.3224353-1-nicoyip.dev@gmail.com \
--to=nicoyip.dev@gmail.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=emil@etsalapatis.com \
--cc=horms@kernel.org \
--cc=jakub@cloudflare.com \
--cc=jiayuan.chen@linux.dev \
--cc=john.fastabend@gmail.com \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=ncardwell@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=stable@vger.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox