]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xfrm: espintcp: do not reuse an in-progress partial send
authorWyatt Feng <bronzed_45_vested@icloud.com>
Tue, 2 Jun 2026 16:46:27 +0000 (00:46 +0800)
committerSteffen Klassert <steffen.klassert@secunet.com>
Fri, 5 Jun 2026 11:20:03 +0000 (13:20 +0200)
espintcp keeps a single in-flight transmit in ctx->partial.
Before building a new sk_msg, espintcp_sendmsg() first tries to flush
that state through espintcp_push_msgs().

For blocking callers, espintcp_push_msgs() may return success even when
the previous partial send is still pending. espintcp_sendmsg() would
then reinitialize emsg->skmsg and reuse ctx->partial while the old
transfer still owns that state.

Do not rebuild the send message when ctx->partial is still in progress.
If espintcp_push_msgs() returns with emsg->len still set, fail the new
send instead of overwriting the live partial state.

This is a memory-safety fix: reusing the live partial-send state can
leave a stale offset attached to a new sk_msg and lead to an out-of-
bounds read in the send path.

tcp_sendmsg_locked() already handles waiting for send buffer memory, so
the fix here is just to preserve espintcp's one-message-at-a-time
transmit state.

Fixes: e27cca96cd68 ("xfrm: add espintcp (RFC 8229)")
Cc: stable@kernel.org
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Assisted-by: Codex:GPT-5.4
Signed-off-by: Wyatt Feng <bronzed_45_vested@icloud.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
net/xfrm/espintcp.c

index a2756186e13a296a18adf3a10397ce58a1557e9a..d9035546375eba5314d64ea33af8660c77523ed1 100644 (file)
@@ -346,6 +346,10 @@ static int espintcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
                        err = -ENOBUFS;
                goto unlock;
        }
+       if (emsg->len) {
+               err = -ENOBUFS;
+               goto unlock;
+       }
 
        sk_msg_init(&emsg->skmsg);
        while (1) {