Skip to content

Commit e9fecc3

Browse files
committed
Merge: mptcp: fix DSS map corruption
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/5418 JIRA: https://issues.redhat.com/browse/RHEL-55470 Tested: vs self-tests This series addresses an issue observed in production and sharing the same root cause with an upstream syzkaller report. The main fix is the second patch in the series. The first one ensure that, should similar issue arise in the future, we will get consistent behavior from the kernel, and suitable introspection. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Approved-by: Davide Caratti <dcaratti@redhat.com> Approved-by: Antoine Tenart <atenart@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Rado Vrbovsky <rvrbovsk@redhat.com>
2 parents d6faebe + e1733b3 commit e9fecc3

File tree

5 files changed

+29
-7
lines changed

5 files changed

+29
-7
lines changed

net/ipv4/tcp_output.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2310,9 +2310,7 @@ static bool tcp_can_coalesce_send_queue_head(struct sock *sk, int len)
23102310
if (len <= skb->len)
23112311
break;
23122312

2313-
if (unlikely(TCP_SKB_CB(skb)->eor) ||
2314-
tcp_has_tx_tstamp(skb) ||
2315-
!skb_pure_zcopy_same(skb, next))
2313+
if (tcp_has_tx_tstamp(skb) || !tcp_skb_can_collapse(skb, next))
23162314
return false;
23172315

23182316
len -= skb->len;

net/mptcp/mib.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ static const struct snmp_mib mptcp_snmp_list[] = {
2424
SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX),
2525
SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC),
2626
SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH),
27+
SNMP_MIB_ITEM("DSSCorruptionFallback", MPTCP_MIB_DSSCORRUPTIONFALLBACK),
28+
SNMP_MIB_ITEM("DSSCorruptionReset", MPTCP_MIB_DSSCORRUPTIONRESET),
2729
SNMP_MIB_ITEM("InfiniteMapTx", MPTCP_MIB_INFINITEMAPTX),
2830
SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX),
2931
SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH),

net/mptcp/mib.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ enum linux_mptcp_mib_field {
1717
MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */
1818
MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */
1919
MPTCP_MIB_DSSNOMATCH, /* Received a new mapping that did not match the previous one */
20+
MPTCP_MIB_DSSCORRUPTIONFALLBACK,/* DSS corruption detected, fallback */
21+
MPTCP_MIB_DSSCORRUPTIONRESET, /* DSS corruption detected, MPJ subflow reset */
2022
MPTCP_MIB_INFINITEMAPTX, /* Sent an infinite mapping */
2123
MPTCP_MIB_INFINITEMAPRX, /* Received an infinite mapping */
2224
MPTCP_MIB_DSSTCPMISMATCH, /* DSS-mapping did not map with TCP's sequence numbers */

net/mptcp/protocol.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,18 @@ static bool mptcp_check_data_fin(struct sock *sk)
618618
return ret;
619619
}
620620

621+
static void mptcp_dss_corruption(struct mptcp_sock *msk, struct sock *ssk)
622+
{
623+
if (READ_ONCE(msk->allow_infinite_fallback)) {
624+
MPTCP_INC_STATS(sock_net(ssk),
625+
MPTCP_MIB_DSSCORRUPTIONFALLBACK);
626+
mptcp_do_fallback(ssk);
627+
} else {
628+
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DSSCORRUPTIONRESET);
629+
mptcp_subflow_reset(ssk);
630+
}
631+
}
632+
621633
static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
622634
struct sock *ssk,
623635
unsigned int *bytes)
@@ -690,10 +702,16 @@ static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
690702
moved += len;
691703
seq += len;
692704

693-
if (WARN_ON_ONCE(map_remaining < len))
694-
break;
705+
if (unlikely(map_remaining < len)) {
706+
DEBUG_NET_WARN_ON_ONCE(1);
707+
mptcp_dss_corruption(msk, ssk);
708+
}
695709
} else {
696-
WARN_ON_ONCE(!fin);
710+
if (unlikely(!fin)) {
711+
DEBUG_NET_WARN_ON_ONCE(1);
712+
mptcp_dss_corruption(msk, ssk);
713+
}
714+
697715
sk_eat_skb(ssk, skb);
698716
done = true;
699717
}

net/mptcp/subflow.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,8 +952,10 @@ static bool skb_is_fully_mapped(struct sock *ssk, struct sk_buff *skb)
952952
unsigned int skb_consumed;
953953

954954
skb_consumed = tcp_sk(ssk)->copied_seq - TCP_SKB_CB(skb)->seq;
955-
if (WARN_ON_ONCE(skb_consumed >= skb->len))
955+
if (unlikely(skb_consumed >= skb->len)) {
956+
DEBUG_NET_WARN_ON_ONCE(1);
956957
return true;
958+
}
957959

958960
return skb->len - skb_consumed <= subflow->map_data_len -
959961
mptcp_subflow_get_map_offset(subflow);

0 commit comments

Comments
 (0)