From: Paolo Abeni <pabeni@xxxxxxxxxx> commit e32d262c89e2b22cb0640223f953b548617ed8a6 upstream. Bugged peer implementation can send corrupted DSS options, consistently hitting a few warning in the data path. Use DEBUG_NET assertions, to avoid the splat on some builds and handle consistently the error, dumping related MIBs and performing fallback and/or reset according to the subflow type. Fixes: 6771bfd9ee24 ("mptcp: update mptcp ack sequence from work queue") Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Paolo Abeni <pabeni@xxxxxxxxxx> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@xxxxxxxxxx> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@xxxxxxxxxx> Link: https://patch.msgid.link/20241008-net-mptcp-fallback-fixes-v1-1-c6fb8e93e551@xxxxxxxxxx Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- net/mptcp/mib.c | 2 ++ net/mptcp/mib.h | 2 ++ net/mptcp/protocol.c | 24 +++++++++++++++++++++--- net/mptcp/subflow.c | 4 +++- 4 files changed, 28 insertions(+), 4 deletions(-) --- a/net/mptcp/mib.c +++ b/net/mptcp/mib.c @@ -26,6 +26,8 @@ static const struct snmp_mib mptcp_snmp_ SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX), SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC), SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH), + SNMP_MIB_ITEM("DSSCorruptionFallback", MPTCP_MIB_DSSCORRUPTIONFALLBACK), + SNMP_MIB_ITEM("DSSCorruptionReset", MPTCP_MIB_DSSCORRUPTIONRESET), SNMP_MIB_ITEM("InfiniteMapTx", MPTCP_MIB_INFINITEMAPTX), SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX), SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH), --- a/net/mptcp/mib.h +++ b/net/mptcp/mib.h @@ -19,6 +19,8 @@ enum linux_mptcp_mib_field { MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */ MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */ MPTCP_MIB_DSSNOMATCH, /* Received a new mapping that did not match the previous one */ + MPTCP_MIB_DSSCORRUPTIONFALLBACK,/* DSS corruption detected, fallback */ + MPTCP_MIB_DSSCORRUPTIONRESET, /* DSS corruption detected, MPJ subflow reset */ MPTCP_MIB_INFINITEMAPTX, /* Sent an infinite mapping */ MPTCP_MIB_INFINITEMAPRX, /* Received an infinite mapping */ MPTCP_MIB_DSSTCPMISMATCH, /* DSS-mapping did not map with TCP's sequence numbers */ --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -630,6 +630,18 @@ static bool mptcp_check_data_fin(struct return ret; } +static void mptcp_dss_corruption(struct mptcp_sock *msk, struct sock *ssk) +{ + if (READ_ONCE(msk->allow_infinite_fallback)) { + MPTCP_INC_STATS(sock_net(ssk), + MPTCP_MIB_DSSCORRUPTIONFALLBACK); + mptcp_do_fallback(ssk); + } else { + MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DSSCORRUPTIONRESET); + mptcp_subflow_reset(ssk); + } +} + static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk, struct sock *ssk, unsigned int *bytes) @@ -702,10 +714,16 @@ static bool __mptcp_move_skbs_from_subfl moved += len; seq += len; - if (WARN_ON_ONCE(map_remaining < len)) - break; + if (unlikely(map_remaining < len)) { + DEBUG_NET_WARN_ON_ONCE(1); + mptcp_dss_corruption(msk, ssk); + } } else { - WARN_ON_ONCE(!fin); + if (unlikely(!fin)) { + DEBUG_NET_WARN_ON_ONCE(1); + mptcp_dss_corruption(msk, ssk); + } + sk_eat_skb(ssk, skb); done = true; } --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -855,8 +855,10 @@ static bool skb_is_fully_mapped(struct s unsigned int skb_consumed; skb_consumed = tcp_sk(ssk)->copied_seq - TCP_SKB_CB(skb)->seq; - if (WARN_ON_ONCE(skb_consumed >= skb->len)) + if (unlikely(skb_consumed >= skb->len)) { + DEBUG_NET_WARN_ON_ONCE(1); return true; + } return skb->len - skb_consumed <= subflow->map_data_len - mptcp_subflow_get_map_offset(subflow); Patches currently in stable-queue which might be from pabeni@xxxxxxxxxx are queue-6.1/icmp-add-counters-for-rate-limits.patch queue-6.1/net-dsa-b53-fix-jumbo-frames-on-10-100-ports.patch queue-6.1/rtnetlink-add-bulk-registration-helpers-for-rtnetlin.patch queue-6.1/net-dsa-b53-allow-lower-mtus-on-bcm5325-5365.patch queue-6.1/r8169-add-tally-counter-fields-added-with-rtl8125.patch queue-6.1/net-add-more-sanity-checks-to-qdisc_pkt_len_init.patch queue-6.1/usbnet-fix-cyclical-race-on-disconnect-with-work-queue.patch queue-6.1/sctp-set-sk_state-back-to-closed-if-autobind-fails-i.patch queue-6.1/vxlan-handle-error-of-rtnl_register_module.patch queue-6.1/net-stmmac-dwmac4-extend-timeout-for-vlan-tag-regist.patch queue-6.1/mctp-handle-error-of-rtnl_register_module.patch queue-6.1/ipv4-ip_gre-fix-drops-of-small-packets-in-ipgre_xmit.patch queue-6.1/net-stmmac-fix-zero-division-error-when-disabling-tc-cbs.patch queue-6.1/net-xilinx-axienet-schedule-napi-in-two-steps.patch queue-6.1/net-stmmac-set-pp_flag_dma_sync_dev-only-if-xdp-is-e.patch queue-6.1/mptcp-fallback-when-mptcp-opts-are-dropped-after-1st-data.patch queue-6.1/mptcp-pm-do-not-remove-closing-subflows.patch queue-6.1/selftests-net-remove-executable-bits-from-library-sc.patch queue-6.1/net-stmmac-dwmac-loongson-init-ref-and-ptp-clocks-ra.patch queue-6.1/net-dsa-b53-fix-max-mtu-for-bcm5325-bcm5365.patch queue-6.1/mptcp-handle-consistently-dss-corruption.patch queue-6.1/net-qrtr-update-packets-cloning-when-broadcasting.patch queue-6.1/net-dsa-b53-fix-max-mtu-for-1g-switches.patch queue-6.1/net-xilinx-axienet-fix-packet-counting.patch queue-6.1/net-dsa-b53-fix-jumbo-frame-mtu-check.patch queue-6.1/bonding-fix-unnecessary-warnings-and-logs-from-bond_.patch queue-6.1/netfilter-nf_reject_ipv6-fix-nf_reject_ip6_tcphdr_pu.patch queue-6.1/net-ethernet-lantiq_etop-fix-memory-disclosure.patch queue-6.1/net-seeq-fix-use-after-free-vulnerability-in-ether3-.patch queue-6.1/ipv4-mask-upper-dscp-bits-and-ecn-bits-in-netlink_fi.patch queue-6.1/net-avoid-potential-underflow-in-qdisc_pkt_len_init-.patch