* [PATCH net v2] xfrm: espintcp: reserve partial message during allocation
@ 2026-10-02 10:24 Bruno Produit
2026-10-02 10:29 ` netdev-bot+sinfo
0 siblings, 1 reply; 2+ messages in thread
From: Bruno Produit @ 2026-10-02 10:24 UTC (permalink / raw)
To: Steffen Klassert, Herbert Xu, David S . Miller
Cc: netdev, Kyle Zeng, linux-kernel, Dominik Czarnota,
Sabrina Dubroca, Bruno Produit, stable
espintcp_sendmsg() builds a new message directly in ctx->partial. If
allocation fails, sk_stream_wait_memory() drops the socket lock while
the shared sk_msg remains unpublished with emsg->len equal to zero. A
concurrent sender can then reuse the same slot. If the first sender is
interrupted, its failure path frees state now owned by the second sender
while TCP may still be consuming it, causing a use-after-free.
Fixes: e27cca96cd68 ("xfrm: add espintcp (RFC 8229)")
Cc: stable@vger.kernel.org
Reported-by: Kyle Zeng <kylebot@openai.com>
Assisted-by: Codex:gpt-5.6-cyber
Signed-off-by: Bruno Produit <bruno.produit@trailofbits.com>
---
Changes in v2:
- Add an ->owned flag to espintcp_msg
- Use ->owned instead of a local sk_msg
v1: https://lore.kernel.org/netdev/20260922145335.2016559-1-bruno.produit@trailofbits.com/
include/net/espintcp.h | 1 +
net/xfrm/espintcp.c | 25 ++++++++++++++++++++-----
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/include/net/espintcp.h b/include/net/espintcp.h
index c70efd704b6d..083c11373c16 100644
--- a/include/net/espintcp.h
+++ b/include/net/espintcp.h
@@ -15,6 +15,7 @@ struct espintcp_msg {
struct sk_buff *skb;
struct sk_msg skmsg;
+ bool owned;
int offset;
int len;
};
struct espintcp_ctx {
diff --git a/net/xfrm/espintcp.c b/net/xfrm/espintcp.c
index 3e72b9f067b9..68b9201c98d3 100644
--- a/net/xfrm/espintcp.c
+++ b/net/xfrm/espintcp.c
@@ -251,6 +251,8 @@ static int espintcp_push_msgs(struct sock *sk, int flags)
struct espintcp_msg *emsg = &ctx->partial;
int err;
+ if (emsg->owned)
+ return -EAGAIN;
if (!emsg->len)
return 0;
@@ -274,6 +276,12 @@ static int espintcp_push_msgs(struct sock *sk, int flags)
return err;
}
+static void espintcp_unreserve_msg(struct sock *sk, struct espintcp_msg *emsg)
+{
+ WRITE_ONCE(emsg->owned, false);
+ sk->sk_write_space(sk);
+}
+
int espintcp_push_skb(struct sock *sk, struct sk_buff *skb)
{
struct espintcp_ctx *ctx = espintcp_getctx(sk);
@@ -291,7 +299,7 @@ int espintcp_push_skb(struct sock *sk, struct sk_buff *skb)
espintcp_push_msgs(sk, 0);
- if (emsg->len) {
+ if (emsg->owned || emsg->len) {
kfree_skb(skb);
return -ENOBUFS;
}
@@ -336,10 +344,11 @@ static int espintcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
err = -ENOBUFS;
goto unlock;
}
- if (emsg->len) {
+ if (emsg->owned || emsg->len) {
err = -ENOBUFS;
goto unlock;
}
+ WRITE_ONCE(emsg->owned, true);
sk_msg_init(&emsg->skmsg);
while (1) {
@@ -368,9 +377,10 @@ static int espintcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
goto fail;
end = emsg->skmsg.sg.end;
- emsg->len = size;
sk_msg_iter_var_prev(end);
sg_mark_end(sk_msg_elem(&emsg->skmsg, end));
+ emsg->len = size;
+ espintcp_unreserve_msg(sk, emsg);
tcp_rate_check_app_limited(sk);
@@ -383,7 +393,7 @@ static int espintcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
fail:
sk_msg_free(sk, &emsg->skmsg);
- memset(emsg, 0, sizeof(*emsg));
+ espintcp_unreserve_msg(sk, emsg);
unlock:
release_sock(sk);
return err;
@@ -549,8 +559,13 @@ static __poll_t espintcp_poll(struct file *file, struct socket *sock,
{
struct sock *sk = sock->sk;
struct espintcp_ctx *ctx = espintcp_getctx(sk);
+ __poll_t mask;
+
+ mask = datagram_poll_queue(file, sock, wait, &ctx->ike_queue);
+ if (READ_ONCE(ctx->partial.owned))
+ mask &= ~(EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND);
- return datagram_poll_queue(file, sock, wait, &ctx->ike_queue);
+ return mask;
}
static void build_protos(struct proto *espintcp_prot,
--
2.53.0
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH net v2] xfrm: espintcp: reserve partial message during allocation
2026-10-02 10:24 [PATCH net v2] xfrm: espintcp: reserve partial message during allocation Bruno Produit
@ 2026-10-02 10:29 ` netdev-bot+sinfo
0 siblings, 0 replies; 2+ messages in thread
From: netdev-bot+sinfo @ 2026-10-02 10:29 UTC (permalink / raw)
To: Bruno Produit
Cc: Steffen Klassert, Herbert Xu, David S . Miller, netdev,
Kyle Zeng, linux-kernel, Dominik Czarnota, Sabrina Dubroca,
stable
Hi!
This is an automated message. This series looks like a fix, but its
commit messages seem to be missing some information:
- Whether the issue was actually triggered, or is only theoretical
(e.g. found by code inspection). If it was triggered please include
the symptoms, like the stack trace or error messages.
Please do not repost the series just to address the above. Instead,
reply to this email with the missing information, so that reviewers
can take it into account. If the series needs another revision for
other reasons, please include the information in the commit messages
then.
The evaluation is done by an LLM so it may be wrong, if you think
that is the case please reply and explain.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-02 10:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-02 10:24 [PATCH net v2] xfrm: espintcp: reserve partial message during allocation Bruno Produit
2026-10-02 10:29 ` netdev-bot+sinfo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®