From: Sasha Levin Date: Sat, 30 Oct 2021 20:33:19 +0000 (-0400) Subject: Fixes for 5.4 X-Git-Tag: v4.4.291~13 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c54528a283b9b7c7ce5c3d35f00bf6c5db744dc1;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/cfg80211-correct-bridge-4addr-mode-check.patch b/queue-5.4/cfg80211-correct-bridge-4addr-mode-check.patch new file mode 100644 index 00000000000..48a3600d322 --- /dev/null +++ b/queue-5.4/cfg80211-correct-bridge-4addr-mode-check.patch @@ -0,0 +1,57 @@ +From 2ff2c6176c71e0d8101ee70fd6a45d5192c4761f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Oct 2021 22:15:46 +0200 +Subject: cfg80211: correct bridge/4addr mode check + +From: Janusz Dziedzic + +[ Upstream commit 689a0a9f505f7bffdefe6f17fddb41c8ab6344f6 ] + +Without the patch we fail: + +$ sudo brctl addbr br0 +$ sudo brctl addif br0 wlp1s0 +$ sudo iw wlp1s0 set 4addr on +command failed: Device or resource busy (-16) + +Last command failed but iface was already in 4addr mode. + +Fixes: ad4bb6f8883a ("cfg80211: disallow bridging managed/adhoc interfaces") +Signed-off-by: Janusz Dziedzic +Link: https://lore.kernel.org/r/20211024201546.614379-1-janusz.dziedzic@gmail.com +[add fixes tag, fix indentation, edit commit log] +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/util.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/net/wireless/util.c b/net/wireless/util.c +index 82b3baed2c7d..aaefaf3422a1 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -975,14 +975,14 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, + !(rdev->wiphy.interface_modes & (1 << ntype))) + return -EOPNOTSUPP; + +- /* if it's part of a bridge, reject changing type to station/ibss */ +- if (netif_is_bridge_port(dev) && +- (ntype == NL80211_IFTYPE_ADHOC || +- ntype == NL80211_IFTYPE_STATION || +- ntype == NL80211_IFTYPE_P2P_CLIENT)) +- return -EBUSY; +- + if (ntype != otype) { ++ /* if it's part of a bridge, reject changing type to station/ibss */ ++ if (netif_is_bridge_port(dev) && ++ (ntype == NL80211_IFTYPE_ADHOC || ++ ntype == NL80211_IFTYPE_STATION || ++ ntype == NL80211_IFTYPE_P2P_CLIENT)) ++ return -EBUSY; ++ + dev->ieee80211_ptr->use_4addr = false; + dev->ieee80211_ptr->mesh_id_up_len = 0; + wdev_lock(dev->ieee80211_ptr); +-- +2.33.0 + diff --git a/queue-5.4/net-use-netif_is_bridge_port-to-check-for-iff_bridge.patch b/queue-5.4/net-use-netif_is_bridge_port-to-check-for-iff_bridge.patch new file mode 100644 index 00000000000..2b4626e1e37 --- /dev/null +++ b/queue-5.4/net-use-netif_is_bridge_port-to-check-for-iff_bridge.patch @@ -0,0 +1,138 @@ +From c534f5ba184975c8a56c434ef2e92f8313362b52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Feb 2020 09:00:07 +0100 +Subject: net: use netif_is_bridge_port() to check for IFF_BRIDGE_PORT + +From: Julian Wiedmann + +[ Upstream commit 2e92a2d0e450740ebe7e7a816162327ad1fde94b ] + +Trivial cleanup, so that all bridge port-specific code can be found in +one go. + +CC: Johannes Berg +CC: Roopa Prabhu +CC: Nikolay Aleksandrov +Signed-off-by: Julian Wiedmann +Reviewed-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 2 +- + drivers/net/ethernet/micrel/ksz884x.c | 2 +- + net/core/rtnetlink.c | 12 ++++++------ + net/wireless/nl80211.c | 2 +- + net/wireless/util.c | 2 +- + 5 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 1949f631e1bc..a7eaf80f500c 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1219,7 +1219,7 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) + skb->dev = bond->dev; + + if (BOND_MODE(bond) == BOND_MODE_ALB && +- bond->dev->priv_flags & IFF_BRIDGE_PORT && ++ netif_is_bridge_port(bond->dev) && + skb->pkt_type == PACKET_HOST) { + + if (unlikely(skb_cow_head(skb, +diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c +index 7dc451fdaf35..2431723bc2fb 100644 +--- a/drivers/net/ethernet/micrel/ksz884x.c ++++ b/drivers/net/ethernet/micrel/ksz884x.c +@@ -5693,7 +5693,7 @@ static void dev_set_promiscuous(struct net_device *dev, struct dev_priv *priv, + * from the bridge. + */ + if ((hw->features & STP_SUPPORT) && !promiscuous && +- (dev->priv_flags & IFF_BRIDGE_PORT)) { ++ netif_is_bridge_port(dev)) { + struct ksz_switch *sw = hw->ksz_switch; + int port = priv->port.first_port; + +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index a53b101ce41a..55c0f32b9375 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -3729,7 +3729,7 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, + + /* Support fdb on master device the net/bridge default case */ + if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) && +- (dev->priv_flags & IFF_BRIDGE_PORT)) { ++ netif_is_bridge_port(dev)) { + struct net_device *br_dev = netdev_master_upper_dev_get(dev); + const struct net_device_ops *ops = br_dev->netdev_ops; + +@@ -3840,7 +3840,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, + + /* Support fdb on master device the net/bridge default case */ + if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) && +- (dev->priv_flags & IFF_BRIDGE_PORT)) { ++ netif_is_bridge_port(dev)) { + struct net_device *br_dev = netdev_master_upper_dev_get(dev); + const struct net_device_ops *ops = br_dev->netdev_ops; + +@@ -4066,13 +4066,13 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) + continue; + + if (!br_idx) { /* user did not specify a specific bridge */ +- if (dev->priv_flags & IFF_BRIDGE_PORT) { ++ if (netif_is_bridge_port(dev)) { + br_dev = netdev_master_upper_dev_get(dev); + cops = br_dev->netdev_ops; + } + } else { + if (dev != br_dev && +- !(dev->priv_flags & IFF_BRIDGE_PORT)) ++ !netif_is_bridge_port(dev)) + continue; + + if (br_dev != netdev_master_upper_dev_get(dev) && +@@ -4084,7 +4084,7 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) + if (idx < s_idx) + goto cont; + +- if (dev->priv_flags & IFF_BRIDGE_PORT) { ++ if (netif_is_bridge_port(dev)) { + if (cops && cops->ndo_fdb_dump) { + err = cops->ndo_fdb_dump(skb, cb, + br_dev, dev, +@@ -4234,7 +4234,7 @@ static int rtnl_fdb_get(struct sk_buff *in_skb, struct nlmsghdr *nlh, + + if (dev) { + if (!ndm_flags || (ndm_flags & NTF_MASTER)) { +- if (!(dev->priv_flags & IFF_BRIDGE_PORT)) { ++ if (!netif_is_bridge_port(dev)) { + NL_SET_ERR_MSG(extack, "Device is not a bridge port"); + return -EINVAL; + } +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 7b170ed6923e..7633d6a74bc2 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -3480,7 +3480,7 @@ static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev, + enum nl80211_iftype iftype) + { + if (!use_4addr) { +- if (netdev && (netdev->priv_flags & IFF_BRIDGE_PORT)) ++ if (netdev && netif_is_bridge_port(netdev)) + return -EBUSY; + return 0; + } +diff --git a/net/wireless/util.c b/net/wireless/util.c +index f0247eab5bc9..82b3baed2c7d 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -976,7 +976,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, + return -EOPNOTSUPP; + + /* if it's part of a bridge, reject changing type to station/ibss */ +- if ((dev->priv_flags & IFF_BRIDGE_PORT) && ++ if (netif_is_bridge_port(dev) && + (ntype == NL80211_IFTYPE_ADHOC || + ntype == NL80211_IFTYPE_STATION || + ntype == NL80211_IFTYPE_P2P_CLIENT)) +-- +2.33.0 + diff --git a/queue-5.4/sctp-add-vtag-check-in-sctp_sf_do_8_5_1_e_sa.patch b/queue-5.4/sctp-add-vtag-check-in-sctp_sf_do_8_5_1_e_sa.patch new file mode 100644 index 00000000000..25916915cf4 --- /dev/null +++ b/queue-5.4/sctp-add-vtag-check-in-sctp_sf_do_8_5_1_e_sa.patch @@ -0,0 +1,65 @@ +From ea857a4738b3d518285bfac2ddd89b129556a153 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Oct 2021 07:42:46 -0400 +Subject: sctp: add vtag check in sctp_sf_do_8_5_1_E_sa + +From: Xin Long + +[ Upstream commit ef16b1734f0a176277b7bb9c71a6d977a6ef3998 ] + +sctp_sf_do_8_5_1_E_sa() is called when processing SHUTDOWN_ACK chunk +in cookie_wait and cookie_echoed state. + +The vtag in the chunk's sctphdr should be verified, otherwise, as +later in chunk length check, it may send abort with the existent +asoc's vtag, which can be exploited by one to cook a malicious +chunk to terminate a SCTP asoc. + +Note that when fails to verify the vtag from SHUTDOWN-ACK chunk, +SHUTDOWN COMPLETE message will still be sent back to peer, but +with the vtag from SHUTDOWN-ACK chunk, as said in 5) of +rfc4960#section-8.4. + +While at it, also remove the unnecessary chunk length check from +sctp_sf_shut_8_4_5(), as it's already done in both places where +it calls sctp_sf_shut_8_4_5(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Xin Long +Acked-by: Marcelo Ricardo Leitner +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/sm_statefuns.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index 35701acbed73..877420868a42 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -3683,12 +3683,6 @@ static enum sctp_disposition sctp_sf_shut_8_4_5( + + SCTP_INC_STATS(net, SCTP_MIB_OUTCTRLCHUNKS); + +- /* If the chunk length is invalid, we don't want to process +- * the reset of the packet. +- */ +- if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr))) +- return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); +- + /* We need to discard the rest of the packet to prevent + * potential bomming attacks from additional bundled chunks. + * This is documented in SCTP Threats ID. +@@ -3716,6 +3710,9 @@ enum sctp_disposition sctp_sf_do_8_5_1_E_sa(struct net *net, + { + struct sctp_chunk *chunk = arg; + ++ if (!sctp_vtag_verify(chunk, asoc)) ++ asoc = NULL; ++ + /* Make sure that the SHUTDOWN_ACK chunk has a valid length. */ + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr))) + return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, +-- +2.33.0 + diff --git a/queue-5.4/sctp-add-vtag-check-in-sctp_sf_ootb.patch b/queue-5.4/sctp-add-vtag-check-in-sctp_sf_ootb.patch new file mode 100644 index 00000000000..46acdbf14b6 --- /dev/null +++ b/queue-5.4/sctp-add-vtag-check-in-sctp_sf_ootb.patch @@ -0,0 +1,47 @@ +From f434d0d89f35df4fabd3e39f007aff8afeb58b31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Oct 2021 07:42:47 -0400 +Subject: sctp: add vtag check in sctp_sf_ootb + +From: Xin Long + +[ Upstream commit 9d02831e517aa36ee6bdb453a0eb47bd49923fe3 ] + +sctp_sf_ootb() is called when processing DATA chunk in closed state, +and many other places are also using it. + +The vtag in the chunk's sctphdr should be verified, otherwise, as +later in chunk length check, it may send abort with the existent +asoc's vtag, which can be exploited by one to cook a malicious +chunk to terminate a SCTP asoc. + +When fails to verify the vtag from the chunk, this patch sets asoc +to NULL, so that the abort will be made with the vtag from the +received chunk later. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Xin Long +Acked-by: Marcelo Ricardo Leitner +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/sm_statefuns.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index 877420868a42..7c6dcbc8e98b 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -3568,6 +3568,9 @@ enum sctp_disposition sctp_sf_ootb(struct net *net, + + SCTP_INC_STATS(net, SCTP_MIB_OUTOFBLUES); + ++ if (asoc && !sctp_vtag_verify(chunk, asoc)) ++ asoc = NULL; ++ + ch = (struct sctp_chunkhdr *)chunk->chunk_hdr; + do { + /* Report violation if the chunk is less then minimal */ +-- +2.33.0 + diff --git a/queue-5.4/sctp-add-vtag-check-in-sctp_sf_violation.patch b/queue-5.4/sctp-add-vtag-check-in-sctp_sf_violation.patch new file mode 100644 index 00000000000..b775c020d48 --- /dev/null +++ b/queue-5.4/sctp-add-vtag-check-in-sctp_sf_violation.patch @@ -0,0 +1,43 @@ +From 04e9b52cd56ca602c4caa4d922be2d8b82f5a999 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Oct 2021 07:42:45 -0400 +Subject: sctp: add vtag check in sctp_sf_violation + +From: Xin Long + +[ Upstream commit aa0f697e45286a6b5f0ceca9418acf54b9099d99 ] + +sctp_sf_violation() is called when processing HEARTBEAT_ACK chunk +in cookie_wait state, and some other places are also using it. + +The vtag in the chunk's sctphdr should be verified, otherwise, as +later in chunk length check, it may send abort with the existent +asoc's vtag, which can be exploited by one to cook a malicious +chunk to terminate a SCTP asoc. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Xin Long +Acked-by: Marcelo Ricardo Leitner +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/sm_statefuns.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index 1e3f6be5bab9..35701acbed73 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -4549,6 +4549,9 @@ enum sctp_disposition sctp_sf_violation(struct net *net, + { + struct sctp_chunk *chunk = arg; + ++ if (!sctp_vtag_verify(chunk, asoc)) ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); ++ + /* Make sure that the chunk has a valid length. */ + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr))) + return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, +-- +2.33.0 + diff --git a/queue-5.4/sctp-fix-the-processing-for-cookie_echo-chunk.patch b/queue-5.4/sctp-fix-the-processing-for-cookie_echo-chunk.patch new file mode 100644 index 00000000000..606dbbf8aec --- /dev/null +++ b/queue-5.4/sctp-fix-the-processing-for-cookie_echo-chunk.patch @@ -0,0 +1,75 @@ +From 83ee29efea6808c1b7d580889bfd38f897d9e1c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Oct 2021 07:42:44 -0400 +Subject: sctp: fix the processing for COOKIE_ECHO chunk + +From: Xin Long + +[ Upstream commit a64b341b8695e1c744dd972b39868371b4f68f83 ] + +1. In closed state: in sctp_sf_do_5_1D_ce(): + + When asoc is NULL, making packet for abort will use chunk's vtag + in sctp_ootb_pkt_new(). But when asoc exists, vtag from the chunk + should be verified before using peer.i.init_tag to make packet + for abort in sctp_ootb_pkt_new(), and just discard it if vtag is + not correct. + +2. In the other states: in sctp_sf_do_5_2_4_dupcook(): + + asoc always exists, but duplicate cookie_echo's vtag will be + handled by sctp_tietags_compare() and then take actions, so before + that we only verify the vtag for the abort sent for invalid chunk + length. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Xin Long +Acked-by: Marcelo Ricardo Leitner +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/sm_statefuns.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index 80e19f5d1738..1e3f6be5bab9 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -697,6 +697,9 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net, + struct sock *sk; + int error = 0; + ++ if (asoc && !sctp_vtag_verify(chunk, asoc)) ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); ++ + /* If the packet is an OOTB packet which is temporarily on the + * control endpoint, respond with an ABORT. + */ +@@ -711,7 +714,8 @@ enum sctp_disposition sctp_sf_do_5_1D_ce(struct net *net, + * in sctp_unpack_cookie(). + */ + if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr))) +- return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); ++ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, ++ commands); + + /* If the endpoint is not listening or if the number of associations + * on the TCP-style socket exceed the max backlog, respond with an +@@ -2141,9 +2145,11 @@ enum sctp_disposition sctp_sf_do_5_2_4_dupcook( + * enough for the chunk header. Cookie length verification is + * done later. + */ +- if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr))) +- return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, +- commands); ++ if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_chunkhdr))) { ++ if (!sctp_vtag_verify(chunk, asoc)) ++ asoc = NULL; ++ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, commands); ++ } + + /* "Decode" the chunk. We have no optional parameters so we + * are in good shape. +-- +2.33.0 + diff --git a/queue-5.4/sctp-fix-the-processing-for-init_ack-chunk.patch b/queue-5.4/sctp-fix-the-processing-for-init_ack-chunk.patch new file mode 100644 index 00000000000..45a70f72896 --- /dev/null +++ b/queue-5.4/sctp-fix-the-processing-for-init_ack-chunk.patch @@ -0,0 +1,135 @@ +From 0a9f0ecac2638bfc76addfa86810e0a81e1a9556 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Oct 2021 07:42:43 -0400 +Subject: sctp: fix the processing for INIT_ACK chunk + +From: Xin Long + +[ Upstream commit 438b95a7c98f77d51cbf4db021f41b602d750a3f ] + +Currently INIT_ACK chunk in non-cookie_echoed state is processed in +sctp_sf_discard_chunk() to send an abort with the existent asoc's +vtag if the chunk length is not valid. But the vtag in the chunk's +sctphdr is not verified, which may be exploited by one to cook a +malicious chunk to terminal a SCTP asoc. + +sctp_sf_discard_chunk() also is called in many other places to send +an abort, and most of those have this problem. This patch is to fix +it by sending abort with the existent asoc's vtag only if the vtag +from the chunk's sctphdr is verified in sctp_sf_discard_chunk(). + +Note on sctp_sf_do_9_1_abort() and sctp_sf_shutdown_pending_abort(), +the chunk length has been verified before sctp_sf_discard_chunk(), +so replace it with sctp_sf_discard(). On sctp_sf_do_asconf_ack() and +sctp_sf_do_asconf(), move the sctp_chunk_length_valid check ahead of +sctp_sf_discard_chunk(), then replace it with sctp_sf_discard(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Xin Long +Acked-by: Marcelo Ricardo Leitner +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/sm_statefuns.c | 37 +++++++++++++++++++------------------ + 1 file changed, 19 insertions(+), 18 deletions(-) + +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index 962b848459f5..80e19f5d1738 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -2280,7 +2280,7 @@ enum sctp_disposition sctp_sf_shutdown_pending_abort( + */ + if (SCTP_ADDR_DEL == + sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) +- return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); + + if (!sctp_err_chunk_valid(chunk)) + return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); +@@ -2326,7 +2326,7 @@ enum sctp_disposition sctp_sf_shutdown_sent_abort( + */ + if (SCTP_ADDR_DEL == + sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) +- return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); + + if (!sctp_err_chunk_valid(chunk)) + return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); +@@ -2596,7 +2596,7 @@ enum sctp_disposition sctp_sf_do_9_1_abort( + */ + if (SCTP_ADDR_DEL == + sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) +- return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); + + if (!sctp_err_chunk_valid(chunk)) + return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); +@@ -3745,6 +3745,11 @@ enum sctp_disposition sctp_sf_do_asconf(struct net *net, + return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); + } + ++ /* Make sure that the ASCONF ADDIP chunk has a valid length. */ ++ if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_addip_chunk))) ++ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, ++ commands); ++ + /* ADD-IP: Section 4.1.1 + * This chunk MUST be sent in an authenticated way by using + * the mechanism defined in [I-D.ietf-tsvwg-sctp-auth]. If this chunk +@@ -3753,13 +3758,7 @@ enum sctp_disposition sctp_sf_do_asconf(struct net *net, + */ + if (!asoc->peer.asconf_capable || + (!net->sctp.addip_noauth && !chunk->auth)) +- return sctp_sf_discard_chunk(net, ep, asoc, type, arg, +- commands); +- +- /* Make sure that the ASCONF ADDIP chunk has a valid length. */ +- if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_addip_chunk))) +- return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, +- commands); ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); + + hdr = (struct sctp_addiphdr *)chunk->skb->data; + serial = ntohl(hdr->serial); +@@ -3888,6 +3887,12 @@ enum sctp_disposition sctp_sf_do_asconf_ack(struct net *net, + return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); + } + ++ /* Make sure that the ADDIP chunk has a valid length. */ ++ if (!sctp_chunk_length_valid(asconf_ack, ++ sizeof(struct sctp_addip_chunk))) ++ return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, ++ commands); ++ + /* ADD-IP, Section 4.1.2: + * This chunk MUST be sent in an authenticated way by using + * the mechanism defined in [I-D.ietf-tsvwg-sctp-auth]. If this chunk +@@ -3896,14 +3901,7 @@ enum sctp_disposition sctp_sf_do_asconf_ack(struct net *net, + */ + if (!asoc->peer.asconf_capable || + (!net->sctp.addip_noauth && !asconf_ack->auth)) +- return sctp_sf_discard_chunk(net, ep, asoc, type, arg, +- commands); +- +- /* Make sure that the ADDIP chunk has a valid length. */ +- if (!sctp_chunk_length_valid(asconf_ack, +- sizeof(struct sctp_addip_chunk))) +- return sctp_sf_violation_chunklen(net, ep, asoc, type, arg, +- commands); ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); + + addip_hdr = (struct sctp_addiphdr *)asconf_ack->skb->data; + rcvd_serial = ntohl(addip_hdr->serial); +@@ -4475,6 +4473,9 @@ enum sctp_disposition sctp_sf_discard_chunk(struct net *net, + { + struct sctp_chunk *chunk = arg; + ++ if (asoc && !sctp_vtag_verify(chunk, asoc)) ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); ++ + /* Make sure that the chunk has a valid length. + * Since we don't know the chunk type, we use a general + * chunkhdr structure to make a comparison. +-- +2.33.0 + diff --git a/queue-5.4/sctp-use-init_tag-from-inithdr-for-abort-chunk.patch b/queue-5.4/sctp-use-init_tag-from-inithdr-for-abort-chunk.patch new file mode 100644 index 00000000000..bf917c45862 --- /dev/null +++ b/queue-5.4/sctp-use-init_tag-from-inithdr-for-abort-chunk.patch @@ -0,0 +1,42 @@ +From b875c49bb4345c57d7acb715bd14647ca5e31d81 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Oct 2021 07:42:41 -0400 +Subject: sctp: use init_tag from inithdr for ABORT chunk + +From: Xin Long + +[ Upstream commit 4f7019c7eb33967eb87766e0e4602b5576873680 ] + +Currently Linux SCTP uses the verification tag of the existing SCTP +asoc when failing to process and sending the packet with the ABORT +chunk. This will result in the peer accepting the ABORT chunk and +removing the SCTP asoc. One could exploit this to terminate a SCTP +asoc. + +This patch is to fix it by always using the initiate tag of the +received INIT chunk for the ABORT chunk to be sent. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Xin Long +Acked-by: Marcelo Ricardo Leitner +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/sm_statefuns.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index 82a202d71a31..962b848459f5 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -6248,6 +6248,7 @@ static struct sctp_packet *sctp_ootb_pkt_new( + * yet. + */ + switch (chunk->chunk_hdr->type) { ++ case SCTP_CID_INIT: + case SCTP_CID_INIT_ACK: + { + struct sctp_initack_chunk *initack; +-- +2.33.0 + diff --git a/queue-5.4/series b/queue-5.4/series index fe3785c02e2..b2f2ce9407b 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -38,3 +38,11 @@ net-nxp-lpc_eth.c-avoid-hang-when-bringing-interface-down.patch net-tls-fix-flipped-sign-in-async_wait.err-assignment.patch phy-phy_ethtool_ksettings_get-lock-the-phy-for-consistency.patch phy-phy_start_aneg-add-an-unlocked-version.patch +sctp-use-init_tag-from-inithdr-for-abort-chunk.patch +sctp-fix-the-processing-for-init_ack-chunk.patch +sctp-fix-the-processing-for-cookie_echo-chunk.patch +sctp-add-vtag-check-in-sctp_sf_violation.patch +sctp-add-vtag-check-in-sctp_sf_do_8_5_1_e_sa.patch +sctp-add-vtag-check-in-sctp_sf_ootb.patch +net-use-netif_is_bridge_port-to-check-for-iff_bridge.patch +cfg80211-correct-bridge-4addr-mode-check.patch