From: David Lee <david.lee@trailofbits.com>
To: matttbe@kernel.org, martineau@kernel.org, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
ncardwell@google.com
Cc: Kyle Zeng <kylebot@openai.com>,
Dominik 'Disconnect3d' Czarnota
<dominik.czarnota@trailofbits.com>,
geliang@kernel.org, horms@kernel.org, kuniyu@google.com,
netdev@vger.kernel.org, mptcp@lists.linux.dev,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
David Lee <david.lee@trailofbits.com>
Subject: [PATCH net] mptcp: hold msk reference when cloning request sockets
Date: Tue, 4 Aug 2026 09:50:49 +0000 [thread overview]
Message-ID: <20260804095051.715355-1-david.lee@trailofbits.com> (raw)
From: Kyle Zeng <kylebot@openai.com>
An MP_JOIN request owns the reference stored in subflow_req->msk.
inet_reqsk_clone() byte-copies that pointer when migrating a request,
but does not acquire a reference for the clone. The original and cloned
request destructors can consequently drop the same reference, leaving
one request with a dangling msk pointer.
Let cloned MPTCP requests take their own msk reference. The source
request still owns its reference while it is being cloned, so sock_hold()
is safe. The clone's normal destructor balances the new reference on
both successful and failed migration paths.
Fixes: c905dee62232 ("tcp: Migrate TCP_NEW_SYN_RECV requests at retransmitting SYN+ACKs.")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6-sol Codex:gpt-5.5-cyber
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Co-developed-by: David Lee <david.lee@trailofbits.com>
Signed-off-by: David Lee <david.lee@trailofbits.com>
---
Bug found and triaged by OpenAI Security Research and
validated by Trail of Bits.
Trail of Bits has a reproducer for this bug that triggers a
KASAN use-after-free and can share if needed.
include/net/mptcp.h | 5 +++++
net/ipv4/inet_connection_sock.c | 10 ++++++++--
net/mptcp/subflow.c | 8 ++++++++
3 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index 71b9fc5a5..51d4b02f5 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -223,6 +223,7 @@ int mptcp_subflow_init_cookie_req(struct request_sock *req,
struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
struct sock *sk_listener,
bool attach_listener);
+void mptcp_subflow_reqsk_clone(struct request_sock *req);
__be32 mptcp_get_reset_option(const struct sk_buff *skb);
@@ -309,6 +310,10 @@ static inline struct request_sock *mptcp_subflow_reqsk_alloc(const struct reques
return NULL;
}
+static inline void mptcp_subflow_reqsk_clone(struct request_sock *req)
+{
+}
+
static inline __be32 mptcp_reset_option(const struct sk_buff *skb) { return htonl(0u); }
static inline void mptcp_active_detect_blackhole(struct sock *sk, bool expired) { }
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 56902bba5..f3ef9c15a 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -17,6 +17,7 @@
#include <net/inet_timewait_sock.h>
#include <net/ip.h>
#include <net/route.h>
+#include <net/mptcp.h>
#include <net/tcp_states.h>
#include <net/xfrm.h>
#include <net/tcp.h>
@@ -946,8 +947,13 @@ static struct request_sock *inet_reqsk_clone(struct request_sock *req,
/* We need not acquire fastopenq->lock
* because the child socket is locked in inet_csk_listen_stop().
*/
- if (sk->sk_protocol == IPPROTO_TCP && tcp_rsk(nreq)->tfo_listener)
- rcu_assign_pointer(tcp_sk(nreq->sk)->fastopen_rsk, nreq);
+ if (sk->sk_protocol == IPPROTO_TCP) {
+ if (tcp_rsk(nreq)->tfo_listener)
+ rcu_assign_pointer(tcp_sk(nreq->sk)->fastopen_rsk, nreq);
+
+ if (rsk_is_mptcp(req))
+ mptcp_subflow_reqsk_clone(nreq);
+ }
return nreq;
}
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 8e386899c..1b6aa5e8c 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -47,6 +47,14 @@ static void subflow_req_destructor(struct request_sock *req)
mptcp_token_destroy_request(req);
}
+void mptcp_subflow_reqsk_clone(struct request_sock *req)
+{
+ struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
+
+ if (subflow_req->msk)
+ sock_hold((struct sock *)subflow_req->msk);
+}
+
static void subflow_generate_hmac(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
void *hmac)
{
--
2.47.3
next reply other threads:[~2026-08-04 9:50 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-04 9:50 David Lee [this message]
2026-08-04 18:00 ` [PATCH net] mptcp: hold msk reference when cloning request sockets Matthieu Baerts
2026-08-05 8:52 ` Yuan Tan
2026-08-05 10:34 ` Matthieu Baerts
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=20260804095051.715355-1-david.lee@trailofbits.com \
--to=david.lee@trailofbits.com \
--cc=davem@davemloft.net \
--cc=dominik.czarnota@trailofbits.com \
--cc=edumazet@google.com \
--cc=geliang@kernel.org \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=kylebot@openai.com \
--cc=linux-kernel@vger.kernel.org \
--cc=martineau@kernel.org \
--cc=matttbe@kernel.org \
--cc=mptcp@lists.linux.dev \
--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