[PATCH mptcp-net v3] mptcp: fix divide-by-zero in __mptcp_push_pending close path

Shardul Bankar posted 1 patch 15 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/multipath-tcp/mptcp_net-next tags/patchew/20260525194828.1137119-1-shardul.b@mpiricsoftware.com
net/mptcp/protocol.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
[PATCH mptcp-net v3] mptcp: fix divide-by-zero in __mptcp_push_pending close path
Posted by Shardul Bankar 15 hours ago
A divide-by-zero in tcp_tso_segs() is reachable via __mptcp_close_ssk
-> __mptcp_push_pending -> mptcp_push_release(ssk, &info) with
info.mss_now == 0, triggered by MPTCP_PM_CMD_FLUSH_ADDRS.

__mptcp_close_ssk() leaves the ssk in a state where __tcp_can_send()
is false (FIN_WAIT1/2, CLOSING, LAST_ACK) and then unconditionally
calls __mptcp_push_pending(sk, 0).  For such an ssk,
mptcp_sendmsg_frag() returns -EAGAIN at its __tcp_can_send() guard
before reaching tcp_send_mss(), so info.mss_now stays 0 when the
trailing mptcp_push_release() feeds it into tcp_push() ->
tcp_tso_autosize().

Reorder mptcp_sendmsg_frag() so tcp_send_mss() runs before the
__tcp_can_send() guard.  info.mss_now is then valid for the trailing
mptcp_push_release() regardless of whether the call ultimately bailed
with -EAGAIN.  tcp_send_mss() is state-independent MSS arithmetic, so
calling it on a non-sendable ssk is safe.

Found by an MPTCP protocol-flow harness extending BRF
(arXiv:2305.08782) via the MPTCP_PM_CMD_FLUSH_ADDRS kernel-PM admin
path; the oops is reached on the first qualifying run.

Fixes: c886d70286bf ("mptcp: do not queue data on closed subflows")
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: Shardul Bankar <shardul.b@mpiricsoftware.com>
---
v3:
- Move the fix from __mptcp_push_pending's ret<=0 branch (slow-path
  release-and-null suggested in v2 review) to mptcp_sendmsg_frag's
  entry: hoist tcp_send_mss() above the __tcp_can_send() guard so
  info.mss_now is always valid before any -EAGAIN exit.  This
  preserves the trailing mptcp_push_release() flush in the normal
  data path, which v2 was inadvertently skipping (7 data-path test
  regressions reported by CI on v2; Paolo: "the check I suggested
  is a bit too rough").
- Fixes tag updated to c886d70286bf (the commit that introduced the
  __tcp_can_send() guard above tcp_send_mss(), creating the bypass
  path this patch closes).
- Reverts v2's release_sock/ssk=NULL additions in
  __mptcp_push_pending; that change is no longer needed.

Link to v2: https://lore.kernel.org/all/20260525003233.857172-1-shardul.b@mpiricsoftware.com/
Link to v1: https://lore.kernel.org/all/20260523211800.2952905-1-shardul.b@mpiricsoftware.com/

 net/mptcp/protocol.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index a72a6ad6ee8b1..3aceb7b1f3214 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -1332,13 +1332,13 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
 			 info->limit > dfrag->data_len))
 		return 0;
 
-	if (unlikely(!__tcp_can_send(ssk)))
-		return -EAGAIN;
-
 	/* compute send limit */
 	if (unlikely(ssk->sk_gso_max_size > MPTCP_MAX_GSO_SIZE))
 		ssk->sk_gso_max_size = MPTCP_MAX_GSO_SIZE;
 	info->mss_now = tcp_send_mss(ssk, &info->size_goal, info->flags);
+	if (unlikely(!__tcp_can_send(ssk)))
+		return -EAGAIN;
+
 	copy = info->size_goal;
 
 	skb = tcp_write_queue_tail(ssk);
-- 
2.34.1
Re: [PATCH mptcp-net v3] mptcp: fix divide-by-zero in __mptcp_push_pending close path
Posted by MPTCP CI 14 hours ago
Hi Shardul,

Thank you for your modifications, that's great!

Our CI did some validations and here is its report:

- KVM Validation: normal (except selftest_mptcp_join): Success! ✅
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Unstable: 1 failed test(s): packetdrill_dss ⚠️ 
- KVM Validation: debug (only selftest_mptcp_join): Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/26417985120

Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/a19f79759720
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1100586


If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:

    $ cd [kernel source code]
    $ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
        --pull always mptcp/mptcp-upstream-virtme-docker:latest \
        auto-normal

For more details:

    https://github.com/multipath-tcp/mptcp-upstream-virtme-docker


Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)