mptcp: mptcp_parse_option() fix for MPTCPOPT_MP_JOIN
authorEric Dumazet <edumazet@google.com>
Thu, 11 Jan 2024 19:49:13 +0000 (19:49 +0000)
committerJakub Kicinski <kuba@kernel.org>
Sat, 13 Jan 2024 02:14:21 +0000 (18:14 -0800)
mptcp_parse_option() currently sets OPTIONS_MPTCP_MPJ, for the three
possible cases handled for MPTCPOPT_MP_JOIN option.

OPTIONS_MPTCP_MPJ is the combination of three flags:
- OPTION_MPTCP_MPJ_SYN
- OPTION_MPTCP_MPJ_SYNACK
- OPTION_MPTCP_MPJ_ACK

This is a problem, because backup, join_id, token, nonce and/or hmac fields
could be left uninitialized in some cases.

Distinguish the three cases, as following patches will need this step.

Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Florian Westphal <fw@strlen.de>
Cc: Peter Krystad <peter.krystad@linux.intel.com>
Cc: Matthieu Baerts <matttbe@kernel.org>
Cc: Mat Martineau <martineau@kernel.org>
Cc: Geliang Tang <geliang.tang@linux.dev>
Reviewed-by: Simon Horman <horms@kernel.org>
Acked-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Mat Martineau <martineau@kernel.org>
Link: https://lore.kernel.org/r/20240111194917.4044654-2-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/mptcp/options.c

index c53914012d01d38c2dc0a3578bf3651595956e72..d2527d189a799319c068a5b76a5816cc7a905861 100644 (file)
@@ -123,8 +123,8 @@ static void mptcp_parse_option(const struct sk_buff *skb,
                break;
 
        case MPTCPOPT_MP_JOIN:
-               mp_opt->suboptions |= OPTIONS_MPTCP_MPJ;
                if (opsize == TCPOLEN_MPTCP_MPJ_SYN) {
+                       mp_opt->suboptions |= OPTION_MPTCP_MPJ_SYN;
                        mp_opt->backup = *ptr++ & MPTCPOPT_BACKUP;
                        mp_opt->join_id = *ptr++;
                        mp_opt->token = get_unaligned_be32(ptr);
@@ -135,6 +135,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
                                 mp_opt->backup, mp_opt->join_id,
                                 mp_opt->token, mp_opt->nonce);
                } else if (opsize == TCPOLEN_MPTCP_MPJ_SYNACK) {
+                       mp_opt->suboptions |= OPTION_MPTCP_MPJ_SYNACK;
                        mp_opt->backup = *ptr++ & MPTCPOPT_BACKUP;
                        mp_opt->join_id = *ptr++;
                        mp_opt->thmac = get_unaligned_be64(ptr);
@@ -145,11 +146,10 @@ static void mptcp_parse_option(const struct sk_buff *skb,
                                 mp_opt->backup, mp_opt->join_id,
                                 mp_opt->thmac, mp_opt->nonce);
                } else if (opsize == TCPOLEN_MPTCP_MPJ_ACK) {
+                       mp_opt->suboptions |= OPTION_MPTCP_MPJ_ACK;
                        ptr += 2;
                        memcpy(mp_opt->hmac, ptr, MPTCPOPT_HMAC_LEN);
                        pr_debug("MP_JOIN hmac");
-               } else {
-                       mp_opt->suboptions &= ~OPTIONS_MPTCP_MPJ;
                }
                break;