All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Geliang Tang" <geliang@kernel.org>, mptcp@lists.linux.dev
Subject: Re: [PATCH mptcp-next v21 8/9] mptcp: sync mptcp skb cb layout with tcp one
Date: Thu, 05 Nov 2026 10:16:47 +0000	[thread overview]
Message-ID: <sashiko-outbox-198832@kernel.org> (raw)
In-Reply-To: <d32bc6dca481d024c23d92e2ef2e51de4eca523c.1793870710.git.tanggeliang@kylinos.cn>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Critical] mptcp: skb_pull() BUG() on nonlinear skb and bad offset in mptcp_init_skb()
- [High] mptcp: wrap-unsafe mapping boundary check in mptcp_init_skb()
--

commit 9d35387c93b4a664b7d58d9f115a8985e1df6730
Author: Paolo Abeni <pabeni@redhat.com>

mptcp: sync mptcp skb cb layout with tcp one

This commit updates struct mptcp_skb_cb to use 32-bit map_seq and end_seq
fields aligned with struct tcp_skb_cb, while adding a 64-bit map_seq64 field
for window validation and coalescing checks.

> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 0666bbfdf2cb8..705b28219883f 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c

[ ... ]

> @@ -437,11 +446,13 @@ static void mptcp_init_skb(struct sock *ssk, struct sk_buff *skb, int offset)
>  
>  	/* the skb map_seq accounts for the skb offset:
>  	 * mptcp_subflow_get_mapped_dsn() is based on the current tp->copied_seq
> -	 * value
> +	 * value; note that end seq number is only available in 32bits format.
>  	 */
> -	MPTCP_SKB_CB(skb)->map_seq = mptcp_subflow_get_mapped_dsn(subflow) -
> -				     offset;
> +	MPTCP_SKB_CB(skb)->map_seq64 = mptcp_subflow_get_mapped_dsn(subflow) -
> +				       offset;
> +	MPTCP_SKB_CB(skb)->map_seq = (u32)MPTCP_SKB_CB(skb)->map_seq64;
>  	MPTCP_SKB_CB(skb)->end_seq = MPTCP_SKB_CB(skb)->map_seq + skb->len;

[Severity: Critical]
As reported by Sashiko on v20 [1], in mptcp_init_skb():

	/* Detect mapping boundary: skb spans multiple mappings */
	if (unlikely(offset > 0 &&
		     TCP_SKB_CB(skb)->seq - subflow->ssn_offset <
		     subflow->map_subflow_seq)) {
		...
		WARN_ON_ONCE(offset >= skb->len);
		skb_pull(skb, offset);
		offset = 0;
	}

	MPTCP_SKB_CB(skb)->map_seq64 = mptcp_subflow_get_mapped_dsn(subflow) -
				       offset;
	MPTCP_SKB_CB(skb)->map_seq = (u32)MPTCP_SKB_CB(skb)->map_seq64;
	MPTCP_SKB_CB(skb)->end_seq = MPTCP_SKB_CB(skb)->map_seq + skb->len;

can calling skb_pull(skb, offset) here trigger a BUG() in __skb_pull() when
the incoming subflow skb is non-linear?

In tcp_data_queue(), the TCP header has already been pulled via __skb_pull().
When the TCP payload resides in page fragments (for example, skbs generated by
mptcp_sendmsg_frag() where only MAX_TCP_HEADER linear space is allocated, GRO
packets, page_pool buffers, or segments coalesced by tcp_try_coalesce()),
skb_headlen(skb) can be 0 or smaller than offset. Because skb_pull() calls
__skb_pull():

	skb->len -= len;
	if (unlikely(skb->len < skb->data_len)) {
		...
		BUG();
	}

pulling offset without pskb_pull() or __pskb_trim_head() reduces skb->len
below skb->data_len and panics the kernel whenever offset > skb_headlen(skb).

Additionally, when offset > 0 within a single DSS mapping (so the mapping
boundary branch is not taken), mptcp_init_skb() leaves the [0, offset) prefix
attached and subtracts offset from map_seq64. Since validate_data_csum() only
validates data starting at tp->copied_seq, if this skb is queued out of order
in __mptcp_move_skb() -> mptcp_data_queue_ofo():

		if (before(seq, MPTCP_SKB_CB(skb1)->end_seq)) {
			if (!after((u32)end_seq, MPTCP_SKB_CB(skb1)->end_seq)) {
				...
			}
			if (after(seq, MPTCP_SKB_CB(skb1)->map_seq)) {
				...
			} else {
				rb_replace_node(&skb1->rbnode, &skb->rbnode,
						&msk->out_of_order_queue);
				mptcp_drop(sk, skb1);
				MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DUPDATA);
				goto merge_right;
			}
		}

won't the offset-shifted map_seq cause mptcp_data_queue_ofo() to replace an
already-validated skb1 at mapped_dsn - offset with the unvalidated [0, offset)
prefix, or prevent mptcp_try_coalesce() when skb1 starts earlier?

[Severity: High]
Also in mptcp_init_skb(), the mapping boundary check compares 32-bit relative
subflow sequence numbers using unsigned <:

	if (unlikely(offset > 0 &&
		     TCP_SKB_CB(skb)->seq - subflow->ssn_offset <
		     subflow->map_subflow_seq)) {

Unlike validate_mapping() in net/mptcp/subflow.c, which uses before():

	u32 ssn = tcp_sk(ssk)->copied_seq - subflow->ssn_offset;

	if (unlikely(before(ssn, subflow->map_subflow_seq))) {

what happens when the 32-bit relative subflow sequence number wraps around
2^32 (or when TCP_SKB_CB(skb)->seq precedes subflow->ssn_offset, such as a
segment overlapping TFO SYN data)?

If the skb starts before the wrap in an old mapping (for example,
TCP_SKB_CB(skb)->seq - subflow->ssn_offset == 0xfffffe00) and the current
mapping starts after the wrap (for example, subflow->map_subflow_seq ==
0x00000100), unsigned < evaluates to false. Wouldn't mptcp_init_skb() then
skip removing the old mapping's prefix bytes and subtract offset from
mptcp_subflow_get_mapped_dsn(subflow), attributing stale prefix bytes from
the old mapping to the new mapping's DSN range [mapped_dsn - offset,
mapped_dsn)? Conversely, if a single mapping straddles the 2^32 wrap boundary,
wouldn't an skb starting after the wrap with offset > 0 falsely satisfy
unsigned < and strip valid prefix bytes?

[1] https://lore.kernel.org/r/cf2994ec4440d24183bea5c407c1962270392c32.1793695518.git.tanggeliang@kylinos.cn

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1793870710.git.tanggeliang@kylinos.cn?part=8

  reply	other threads:[~2026-11-05 10:16 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05  9:43 [PATCH mptcp-next v21 0/9] Reduce the differences between TCP and MPTCP for TLS usage Geliang Tang
2026-11-05  9:43 ` [PATCH mptcp-net v21 1/9] mptcp: fix TFO SIOCINQ overflow in mptcp_inq_hint Geliang Tang
2026-11-06 23:07   ` netdev-bot+sashiko
2026-11-05  9:43 ` [PATCH mptcp-next v21 2/9] selftests: mptcp: connect: check TFO SIOCINQ overflow Geliang Tang
2026-11-06 23:07   ` netdev-bot+sashiko
2026-11-05  9:43 ` [PATCH mptcp-net v21 3/9] mptcp: fix TFO map_seq sign extension in fastopen Geliang Tang
2026-11-06 23:07   ` netdev-bot+sashiko
2026-11-05  9:43 ` [PATCH mptcp-net v21 4/9] mptcp: fix fallback dummy mapping anchor Geliang Tang
2026-11-05  9:43 ` [PATCH mptcp-next v21 5/9] mptcp: drop the mptcp_ooo_try_coalesce() helper Geliang Tang
2026-11-05  9:43 ` [PATCH mptcp-next v21 6/9] mptcp: drop the cant_coalesce CB field Geliang Tang
2026-11-05  9:43 ` [PATCH mptcp-next v21 7/9] mptcp: remove CB offset field Geliang Tang
2026-11-05 10:13   ` sashiko-bot
2026-11-06 23:07   ` netdev-bot+sashiko
2026-11-05  9:43 ` [PATCH mptcp-next v21 8/9] mptcp: sync mptcp skb cb layout with tcp one Geliang Tang
2026-11-05 10:16   ` sashiko-bot [this message]
2026-11-06 23:07   ` netdev-bot+sashiko
2026-11-05  9:43 ` [PATCH mptcp-next v21 9/9] mptcp: defer read_sock cleanup to mptcp_worker Geliang Tang
2026-11-06 23:07   ` netdev-bot+sashiko
2026-11-05 11:38 ` [PATCH mptcp-next v21 0/9] Reduce the differences between TCP and MPTCP for TLS usage MPTCP CI

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=sashiko-outbox-198832@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=geliang@kernel.org \
    --cc=mptcp@lists.linux.dev \
    --cc=sashiko-reviews@lists.linux.dev \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.