From e6f57200f56967ef6526383615bcac284024ca1f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 18 Oct 2023 13:02:27 +0000 Subject: [PATCH] Revert "netfilter: handle the connecting collision properly in nf_conntrack_proto_sctp" This reverts commit f110aa377ddc0aa4e604e36ccb0a72b3e89db16e which is commit 8e56b063c86569e51eed1c5681ce6361fa97fc7a upstream. 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 e7545bcca805..21cbaf6dac33 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;