Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'mptcp-fix-warn-on-bad-status'

Matthieu Baerts says:

====================
mptcp: fix warn on bad status

Two somewhat related fixes addressing different issues found by
syzkaller, and producing the exact same splat: a WARNING in
subflow_data_ready().

- Patch 1: fallback earlier on simultaneous connections to avoid a
warning. A fix for v5.19.

- Patch 2: ensure context reset on disconnect, also to avoid a similar
warning. A fix for v6.2.

Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
====================

Link: https://patch.msgid.link/20251212-net-mptcp-subflow_data_ready-warn-v1-0-d1f9fd1c36c8@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+19 -14
+10
net/mptcp/options.c
··· 408 408 */ 409 409 subflow->snd_isn = TCP_SKB_CB(skb)->end_seq; 410 410 if (subflow->request_mptcp) { 411 + if (unlikely(subflow_simultaneous_connect(sk))) { 412 + WARN_ON_ONCE(!mptcp_try_fallback(sk, MPTCP_MIB_SIMULTCONNFALLBACK)); 413 + 414 + /* Ensure mptcp_finish_connect() will not process the 415 + * MPC handshake. 416 + */ 417 + subflow->request_mptcp = 0; 418 + return false; 419 + } 420 + 411 421 opts->suboptions = OPTION_MPTCP_MPC_SYN; 412 422 opts->csum_reqd = mptcp_is_checksum_enabled(sock_net(sk)); 413 423 opts->allow_join_id0 = mptcp_allow_join_id0(sock_net(sk));
+5 -3
net/mptcp/protocol.c
··· 2467 2467 */ 2468 2468 static void __mptcp_subflow_disconnect(struct sock *ssk, 2469 2469 struct mptcp_subflow_context *subflow, 2470 - unsigned int flags) 2470 + bool fastclosing) 2471 2471 { 2472 2472 if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || 2473 - subflow->send_fastclose) { 2473 + fastclosing) { 2474 2474 /* The MPTCP code never wait on the subflow sockets, TCP-level 2475 2475 * disconnect should never fail 2476 2476 */ ··· 2538 2538 2539 2539 need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk); 2540 2540 if (!dispose_it) { 2541 - __mptcp_subflow_disconnect(ssk, subflow, flags); 2541 + __mptcp_subflow_disconnect(ssk, subflow, msk->fastclosing); 2542 2542 release_sock(ssk); 2543 2543 2544 2544 goto out; ··· 2884 2884 2885 2885 mptcp_set_state(sk, TCP_CLOSE); 2886 2886 mptcp_backlog_purge(sk); 2887 + msk->fastclosing = 1; 2887 2888 2888 2889 /* Explicitly send the fastclose reset as need */ 2889 2890 if (__mptcp_check_fallback(msk)) ··· 3419 3418 msk->bytes_sent = 0; 3420 3419 msk->bytes_retrans = 0; 3421 3420 msk->rcvspace_init = 0; 3421 + msk->fastclosing = 0; 3422 3422 3423 3423 /* for fallback's sake */ 3424 3424 WRITE_ONCE(msk->ack_seq, 0);
+4 -5
net/mptcp/protocol.h
··· 320 320 fastopening:1, 321 321 in_accept_queue:1, 322 322 free_first:1, 323 - rcvspace_init:1; 323 + rcvspace_init:1, 324 + fastclosing:1; 324 325 u32 notsent_lowat; 325 326 int keepalive_cnt; 326 327 int keepalive_idle; ··· 1338 1337 { 1339 1338 struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); 1340 1339 1341 - return (1 << sk->sk_state) & 1342 - (TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_FIN_WAIT2 | TCPF_CLOSING) && 1343 - is_active_ssk(subflow) && 1344 - !subflow->conn_finished; 1340 + /* Note that the sk state implies !subflow->conn_finished. */ 1341 + return sk->sk_state == TCP_SYN_RECV && is_active_ssk(subflow); 1345 1342 } 1346 1343 1347 1344 #ifdef CONFIG_SYN_COOKIES
-6
net/mptcp/subflow.c
··· 1878 1878 1879 1879 __subflow_state_change(sk); 1880 1880 1881 - if (subflow_simultaneous_connect(sk)) { 1882 - WARN_ON_ONCE(!mptcp_try_fallback(sk, MPTCP_MIB_SIMULTCONNFALLBACK)); 1883 - subflow->conn_finished = 1; 1884 - mptcp_propagate_state(parent, sk, subflow, NULL); 1885 - } 1886 - 1887 1881 /* as recvmsg() does not acquire the subflow socket for ssk selection 1888 1882 * a fin packet carrying a DSS can be unnoticed if we don't trigger 1889 1883 * the data available machinery here.