All of lore.kernel.org
 help / color / mirror / Atom feed
From: Geliang Tang <geliang@kernel.org>
To: sashiko-reviews@lists.linux.dev,
	"Matthieu Baerts (NGI0)" <matttbe@kernel.org>,
	MPTCP Linux <mptcp@lists.linux.dev>
Subject: Re: [PATCH mptcp-next v3 2/3] mptcp: options: track invalid suboptions
Date: Fri, 30 Oct 2026 11:14:40 +0800	[thread overview]
Message-ID: <9ac7b40bab2bcec633cf3ed199022781f8f3f13e.camel@kernel.org> (raw)
In-Reply-To: <sashiko-outbox-190022@kernel.org>

On Thu, 2026-10-29 at 21:52 +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential
> issue(s) to consider:
> - [Medium] mptcp: missing invalid option checks in
> mptcp_parse_option()
> --
> 
> commit e7e04837e80d59cf3334575f91dc516262bef4d7
> Author: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> 
> mptcp: options: track invalid suboptions
> 
> This commit adds the MPTCP_MIB_OPTINVALID MIB counter to track
> incoming
> MPTCP options that have invalid sizes or unexpected suboption
> combinations.
> 
> > diff --git a/net/mptcp/options.c b/net/mptcp/options.c
> > index cbc105199073e..10a150e2ad69e 100644
> > --- a/net/mptcp/options.c
> > +++ b/net/mptcp/options.c
> > @@ -20,7 +20,7 @@ static bool mptcp_cap_flag_sha256(u8 flags)
> >  	return (flags & MPTCP_CAP_FLAG_MASK) ==
> > MPTCP_CAP_HMAC_SHA256;
> >  }
> >  
> > -static void mptcp_parse_option(const struct sk_buff *skb,
> > +static void mptcp_parse_option(const struct sock *sk, const struct
> > sk_buff *skb,
> >  			       const unsigned char *ptr, int
> > opsize,
> >  			       struct mptcp_options_received
> > *mp_opt)
> >  {
> 
> [ ... ]
> 
> > @@ -175,7 +177,7 @@ static void mptcp_parse_option(const struct
> > sk_buff *skb,
> >  					    OPTION_MPTCP_PRIO |
> >  					    OPTION_MPTCP_FASTCLOSE
> > |
> >  					    OPTION_MPTCP_FAIL)) !=
> > 0)
> > -			break;
> > +			goto invalid;
> >  
> >  		pr_debug("DSS\n");
> >  		ptr++;
> > @@ -218,7 +220,7 @@ static void mptcp_parse_option(const struct
> > sk_buff *skb,
> >  			mp_opt->ack64 = 0;
> >  			mp_opt->use_ack = 0;
> >  			mp_opt->data_fin = 0;
> > -			break;
> > +			goto invalid;
> >  		}
> >  
> >  		mp_opt->suboptions |= OPTION_MPTCP_DSS;
> 
> [ ... ]
> 
> > @@ -386,10 +388,10 @@ static void mptcp_parse_option(const struct
> > sk_buff *skb,
> >  		/* Can be used with a restricted number of other
> > options */
> >  		if ((mp_opt->suboptions & ~(OPTION_MPTCP_FAIL |
> >  					   
> > OPTION_MPTCP_FASTCLOSE)) != 0)
> > -			break;
> > +			goto invalid;
> >  
> >  		if (opsize != TCPOLEN_MPTCP_RST)
> > -			break;
> > +			goto invalid;
> >  
> >  		if (!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST))
> >  			break;
> 
> [ ... ]
> 
> > @@ -418,11 +420,17 @@ static void mptcp_parse_option(const struct
> > sk_buff *skb,
> >  		break;
> >  
> >  	default:
> > +		/* Not invalid: maybe used for experimentations */
> >  		break;
> >  	}
> > +
> > +	return;
> > +
> > +invalid:
> > +	MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_OPTINVALID);
> >  }
> 
> [Severity: Medium]
> Can a couple of invalid option cases in
> net/mptcp/options.c:mptcp_parse_option()
> still read out of bounds or miss incrementing MPTCP_MIB_OPTINVALID?
> 
> First, mptcp_get_options() only rejects opsize < 2 before calling
> mptcp_parse_option():
> 
> net/mptcp/options.c:mptcp_get_options()
> 	opsize = *ptr++;
> 	if (opsize < 2) /* "silly options" */
> 		return;
> 	if (opsize > length)
> 		return;	/* don't parse partial options */
> 	if (opcode == TCPOPT_MPTCP)
> 		mptcp_parse_option(sk, skb, ptr, opsize,
> 				   mp_opt);
> 
> When opsize == 2, ptr already points past the end of the 2-byte
> option.
> At the start of mptcp_parse_option(), *ptr is dereferenced before
> checking
> opsize:
> 
> net/mptcp/options.c:mptcp_parse_option()
> 	u8 subtype = *ptr >> 4;
> 
> If the byte following the 2-byte option has an upper nibble in the
> default
> range (9..15), switch (subtype) hits default: break and returns
> without
> incrementing MPTCP_MIB_OPTINVALID. Similarly, if opsize is 2 or 3 and
> subtype is MPTCPOPT_DSS, the MPTCPOPT_DSS case advances ptr and reads
> a
> 4th byte before validating opsize against expected_opsize (minimum
> TCPOLEN_MPTCP_DSS_BASE == 4):
> 
> 	case MPTCPOPT_DSS:
> 		...
> 		ptr++;
> 
> 		flags = (*ptr++) & MPTCP_DSS_FLAG_MASK;

These could be addressed by adding an "opsize < 3" check at the
beginning of mptcp_parse_option(). However, this issue wasn't
introduced by this patch - I think they can be ignored for now and
addressed in a separate patch if needed.

> 
> Second, in the MPTCPOPT_RST case:
> 
> 		if (!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST))
> 			break;

Indeed, this should use goto invalid; instead of break. WDYT?

Thanks,
-Geliang

> 
> If a peer sends an MP_RST suboption on a packet without TCPHDR_RST
> set, it
> breaks out instead of jumping to invalid. Aside from not incrementing
> MPTCP_MIB_OPTINVALID, this leaves OPTION_MPTCP_RST unset in
> mp_opt->suboptions, so a packet carrying MP_RST followed by DSS on a
> non-RST segment will accept the DSS option without flagging the
> invalid
> MP_RST + DSS combination.
> 
> Should mptcp_parse_option() check for a minimum opsize (and minimum
> DSS
> size before reading flags) and jump to invalid when MPTCPOPT_RST is
> received without TCPHDR_RST?

  reply	other threads:[~2026-10-30  3:14 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-29 21:05 [PATCH mptcp-next v3 0/3] mptcp: options: MIB for invalid & drop suboptions Matthieu Baerts (NGI0)
2026-10-29 21:05 ` [PATCH mptcp-next v3 1/3] mptcp: options: use a dedicated bit for csum reqd Matthieu Baerts (NGI0)
2026-10-30  2:55   ` Geliang Tang
2026-10-29 21:05 ` [PATCH mptcp-next v3 2/3] mptcp: options: track invalid suboptions Matthieu Baerts (NGI0)
2026-10-29 21:52   ` sashiko-bot
2026-10-30  3:14     ` Geliang Tang [this message]
2026-10-30 11:34     ` Matthieu Baerts
2026-10-29 21:05 ` [PATCH mptcp-next v3 3/3] mptcp: options: reset parsing in case of invalidity Matthieu Baerts (NGI0)
2026-10-30  2:56   ` Geliang Tang
2026-10-29 23:04 ` [PATCH mptcp-next v3 0/3] mptcp: options: MIB for invalid & drop suboptions 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=9ac7b40bab2bcec633cf3ed199022781f8f3f13e.camel@kernel.org \
    --to=geliang@kernel.org \
    --cc=matttbe@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.