From: netdev-bot+sashiko@kernel.org
To: matttbe@kernel.org
Cc: martineau@kernel.org, geliang@kernel.org, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
horms@kernel.org, netdev@vger.kernel.org, mptcp@lists.linux.dev,
stable@vger.kernel.org, shardul.b@mpiricsoftware.com,
xinyang@anthropic.com
Subject: Re: [PATCH net 2/2] mptcp: close race between scheduler and state change
Date: Wed, 16 Sep 2026 20:45:36 +0000 [thread overview]
Message-ID: <178959153630.22033.1222004531183755077@kernel.org> (raw)
In-Reply-To: <20260915-net-mptcp-misc-fixes-7-3-rc4-v1-2-a257797dd5d0@kernel.org>
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider:
Critical: 0 · High: 1 · Medium: 0 · Low: 0
- [High] Incomplete fix: the identical `mss_now == 0` divide-by-zero that
the patch guards in `mptcp_push_release()` (net/mptcp/protocol.c:1667)…
--
mptcp: close race between scheduler and state change
The patch guards the tcp_push() call in mptcp_push_release() with a check
for info->mss_now being non-zero, so that a subflow which failed
transmission (leaving mss_now at 0) is not used for a divide operation.
Closes: https://lore.kernel.org/20260525194828.1137119-1-shardul.b@mpiricsoftware.com
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 0098e28309318..709610db3ce9d 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -1664,7 +1664,9 @@ struct sock *mptcp_subflow_get_send(struct mptcp_sock *msk)
>
> static void mptcp_push_release(struct sock *ssk, struct mptcp_sendmsg_info *info)
> {
> - tcp_push(ssk, 0, info->mss_now, tcp_sk(ssk)->nonagle, info->size_goal);
> + if (info->mss_now)
> + tcp_push(ssk, 0, info->mss_now, tcp_sk(ssk)->nonagle,
> + info->size_goal);
> release_sock(ssk);
> }
[Severity: High]
Should the same guard also be added to the second tcp_push() call site, in
__mptcp_subflow_push_pending()?
That function starts with a zeroed info:
net/mptcp/protocol.c:__mptcp_subflow_push_pending() {
struct mptcp_sendmsg_info info = {
.data_lock_held = true,
};
...
int copied = 0;
and info.mss_now is only ever assigned inside mptcp_sendmsg_frag(), after
the early return the commit message refers to:
if (unlikely(!__tcp_can_send(ssk)))
return -EAGAIN;
/* compute send limit */
...
info->mss_now = tcp_send_mss(ssk, &info->size_goal, info->flags);
In the non-first iteration, the return value is accumulated into copied
without filtering negatives:
net/mptcp/protocol.c:__mptcp_subflow_push_pending() {
if (READ_ONCE(subflow->scheduled)) {
mptcp_subflow_set_scheduled(subflow, false);
ret = __subflow_push_pending(sk, ssk, &info);
if (ret <= 0)
keep_pushing = false;
copied += ret;
}
__subflow_push_pending() passes mptcp_sendmsg_frag()'s -EAGAIN through
verbatim when the first frag fails, so copied becomes -EAGAIN, which is
non-zero, while info.mss_now is still 0:
out:
if (copied) {
tcp_push(ssk, 0, info.mss_now, tcp_sk(ssk)->nonagle,
info.size_goal);
Can that reach the divide the patch is trying to avoid? With a non-empty
subflow write queue, tcp_push() does not take the autocork early return
(it requires skb->len < size_goal, i.e. skb->len < 0), so it calls
__tcp_push_pending_frames(sk, 0, nonagle), which only bails for TCP_CLOSE.
For FIN_WAIT1/FIN_WAIT2/CLOSING/LAST_ACK it continues into
tcp_write_xmit(sk, 0, ...) and tcp_tso_segs() -> tcp_tso_autosize():
net/ipv4/tcp_output.c:tcp_tso_autosize() {
return max_t(u32, bytes / mss_now, min_tso_segs);
tcp_set_skb_tso_segs() has the same shape with
DIV_ROUND_UP(skb->len, mss_now).
Is the "scheduled but no longer sendable" state reachable on this path?
mptcp_sched_get_send() returns early without re-validating sendability if
any subflow already has the flag set:
net/mptcp/sched.c:mptcp_sched_get_send() {
mptcp_for_each_subflow(msk, subflow) {
if (READ_ONCE(subflow->scheduled))
return 0;
}
and __mptcp_subflow_push_pending() itself leaves the flag set on the
subflows it delegates via mptcp_subflow_delegate(). The tree also comments
on leftover flags elsewhere ("there could be left-over scheduled subflows;
clear them all or later xmit could use bad ones"), and
__mptcp_push_pending() already anticipates -EAGAIN together with
FIN_WAIT1/FIN_WAIT2 - which are exactly the states where
__tcp_push_pending_frames() does not bail out.
The entry point with first == false is __mptcp_check_push():
if (!sock_owned_by_user(sk))
__mptcp_subflow_push_pending(sk, ssk, false);
reached from ack_update_msk() in net/mptcp/options.c on incoming DSS acks,
so this runs in softirq context on peer-supplied input.
A second, smaller question on the same statement: since copied mixes byte
counts with negative errnos, can a positive count followed by an error that
sums to exactly zero (for example 11 bytes then -EAGAIN) make the
if (copied) test false and skip both the flush and
mptcp_reset_rtx_timer() even though data was queued?
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260915-net-mptcp-misc-fixes-7-3-rc4-v1-0-a257797dd5d0%40kernel.org
next prev parent reply other threads:[~2026-09-16 20:45 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-15 20:37 [PATCH net 0/2] mptcp: misc fixes for v7.3-rc4 Matthieu Baerts (NGI0)
2026-09-15 20:37 ` [PATCH net 1/2] mptcp: avoid unneeded actions on subflow reset Matthieu Baerts (NGI0)
2026-09-16 20:45 ` netdev-bot+sashiko
2026-09-17 11:14 ` Paolo Abeni
2026-09-15 20:37 ` [PATCH net 2/2] mptcp: close race between scheduler and state change Matthieu Baerts (NGI0)
2026-09-16 20:45 ` netdev-bot+sashiko [this message]
2026-09-17 11:16 ` Paolo Abeni
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=178959153630.22033.1222004531183755077@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=geliang@kernel.org \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=martineau@kernel.org \
--cc=matttbe@kernel.org \
--cc=mptcp@lists.linux.dev \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=shardul.b@mpiricsoftware.com \
--cc=stable@vger.kernel.org \
--cc=xinyang@anthropic.com \
/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