From 92a425f8ff658fba32dbb9edab7a71666d14a28f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 24 Oct 2023 12:43:53 +0000 Subject: [PATCH] Revert "netfilter: handle the connecting collision properly in nf_conntrack_proto_sctp" This reverts commit 00d35e6b1672b973a2bf8de1cb8167b287aa5797 which is commit 8e56b063c86569e51eed1c5681ce6361fa97fc7a uptream. It breaks the Android ABI so revert it for now, if it is needed in the future, it can be brought back in an ABI-safe way. Bug: 161946584 Change-Id: Ia03ea49365e6ce063194738b22f77d2a403ea3a4 Signed-off-by: Greg Kroah-Hartman --- include/linux/netfilter/nf_conntrack_sctp.h | 1 - net/netfilter/nf_conntrack_proto_sctp.c | 43 +++++---------------- 2 files changed, 10 insertions(+), 34 deletions(-) diff --git a/include/linux/netfilter/nf_conntrack_sctp.h b/include/linux/netfilter/nf_conntrack_sctp.h index fb31312825ae..625f491b95de 100644 --- a/include/linux/netfilter/nf_conntrack_sctp.h +++ b/include/linux/netfilter/nf_conntrack_sctp.h @@ -9,7 +9,6 @@ struct ip_ct_sctp { enum sctp_conntrack state; __be32 vtag[IP_CT_DIR_MAX]; - u8 init[IP_CT_DIR_MAX]; u8 last_dir; u8 flags; }; diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index c94a9971d790..7247af51bdfc 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -112,7 +112,7 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = { /* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA, sSA}, /* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't have Stale cookie*/ /* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA, sCL},/* 5.2.4 - Big TODO */ -/* cookie_ack */ {sCL, sCL, sCW, sES, sES, sSS, sSR, sSA, sCL},/* Can't come in orig dir */ +/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't come in orig dir */ /* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL, sCL}, /* heartbeat */ {sHS, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, /* heartbeat_ack*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, @@ -126,7 +126,7 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = { /* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA, sIV}, /* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA, sIV}, /* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA, sIV}, -/* cookie_echo */ {sIV, sCL, sCE, sCE, sES, sSS, sSR, sSA, sIV},/* Can't come in reply dir */ +/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV},/* Can't come in reply dir */ /* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA, sIV}, /* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL, sIV}, /* heartbeat */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, @@ -426,9 +426,6 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct, /* (D) vtag must be same as init_vtag as found in INIT_ACK */ if (sh->vtag != ct->proto.sctp.vtag[dir]) goto out_unlock; - } else if (sch->type == SCTP_CID_COOKIE_ACK) { - ct->proto.sctp.init[dir] = 0; - ct->proto.sctp.init[!dir] = 0; } else if (sch->type == SCTP_CID_HEARTBEAT) { if (ct->proto.sctp.vtag[dir] == 0) { pr_debug("Setting %d vtag %x for dir %d\n", sch->type, sh->vtag, dir); @@ -477,18 +474,16 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct, } /* If it is an INIT or an INIT ACK note down the vtag */ - if (sch->type == SCTP_CID_INIT) { - struct sctp_inithdr _ih, *ih; + if (sch->type == SCTP_CID_INIT || + sch->type == SCTP_CID_INIT_ACK) { + struct sctp_inithdr _inithdr, *ih; - ih = skb_header_pointer(skb, offset + sizeof(_sch), sizeof(*ih), &_ih); - if (!ih) + ih = skb_header_pointer(skb, offset + sizeof(_sch), + sizeof(_inithdr), &_inithdr); + if (ih == NULL) goto out_unlock; - - if (ct->proto.sctp.init[dir] && ct->proto.sctp.init[!dir]) - ct->proto.sctp.init[!dir] = 0; - ct->proto.sctp.init[dir] = 1; - - pr_debug("Setting vtag %x for dir %d\n", ih->init_tag, !dir); + pr_debug("Setting vtag %x for dir %d\n", + ih->init_tag, !dir); ct->proto.sctp.vtag[!dir] = ih->init_tag; /* don't renew timeout on init retransmit so @@ -499,24 +494,6 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct, old_state == SCTP_CONNTRACK_CLOSED && nf_ct_is_confirmed(ct)) ignore = true; - } else if (sch->type == SCTP_CID_INIT_ACK) { - struct sctp_inithdr _ih, *ih; - __be32 vtag; - - ih = skb_header_pointer(skb, offset + sizeof(_sch), sizeof(*ih), &_ih); - if (!ih) - goto out_unlock; - - vtag = ct->proto.sctp.vtag[!dir]; - if (!ct->proto.sctp.init[!dir] && vtag && vtag != ih->init_tag) - goto out_unlock; - /* collision */ - if (ct->proto.sctp.init[dir] && ct->proto.sctp.init[!dir] && - vtag != ih->init_tag) - goto out_unlock; - - pr_debug("Setting vtag %x for dir %d\n", ih->init_tag, !dir); - ct->proto.sctp.vtag[!dir] = ih->init_tag; } ct->proto.sctp.state = new_state;