]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Sat, 30 Oct 2021 20:33:19 +0000 (16:33 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 30 Oct 2021 20:33:19 +0000 (16:33 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.4/cfg80211-correct-bridge-4addr-mode-check.patch [new file with mode: 0644]
queue-5.4/net-use-netif_is_bridge_port-to-check-for-iff_bridge.patch [new file with mode: 0644]
queue-5.4/sctp-add-vtag-check-in-sctp_sf_do_8_5_1_e_sa.patch [new file with mode: 0644]
queue-5.4/sctp-add-vtag-check-in-sctp_sf_ootb.patch [new file with mode: 0644]
queue-5.4/sctp-add-vtag-check-in-sctp_sf_violation.patch [new file with mode: 0644]
queue-5.4/sctp-fix-the-processing-for-cookie_echo-chunk.patch [new file with mode: 0644]
queue-5.4/sctp-fix-the-processing-for-init_ack-chunk.patch [new file with mode: 0644]
queue-5.4/sctp-use-init_tag-from-inithdr-for-abort-chunk.patch [new file with mode: 0644]
queue-5.4/series

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 (file)
index 0000000..48a3600
--- /dev/null
@@ -0,0 +1,57 @@
+From 2ff2c6176c71e0d8101ee70fd6a45d5192c4761f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Oct 2021 22:15:46 +0200
+Subject: cfg80211: correct bridge/4addr mode check
+
+From: Janusz Dziedzic <janusz.dziedzic@gmail.com>
+
+[ 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 <janusz.dziedzic@gmail.com>
+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 <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..2b4626e
--- /dev/null
@@ -0,0 +1,138 @@
+From c534f5ba184975c8a56c434ef2e92f8313362b52 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <jwi@linux.ibm.com>
+
+[ Upstream commit 2e92a2d0e450740ebe7e7a816162327ad1fde94b ]
+
+Trivial cleanup, so that all bridge port-specific code can be found in
+one go.
+
+CC: Johannes Berg <johannes@sipsolutions.net>
+CC: Roopa Prabhu <roopa@cumulusnetworks.com>
+CC: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
+Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..2591691
--- /dev/null
@@ -0,0 +1,65 @@
+From ea857a4738b3d518285bfac2ddd89b129556a153 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <lucien.xin@gmail.com>
+
+[ 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 <lucien.xin@gmail.com>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..46acdbf
--- /dev/null
@@ -0,0 +1,47 @@
+From f434d0d89f35df4fabd3e39f007aff8afeb58b31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Oct 2021 07:42:47 -0400
+Subject: sctp: add vtag check in sctp_sf_ootb
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ 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 <lucien.xin@gmail.com>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..b775c02
--- /dev/null
@@ -0,0 +1,43 @@
+From 04e9b52cd56ca602c4caa4d922be2d8b82f5a999 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Oct 2021 07:42:45 -0400
+Subject: sctp: add vtag check in sctp_sf_violation
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ 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 <lucien.xin@gmail.com>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..606dbbf
--- /dev/null
@@ -0,0 +1,75 @@
+From 83ee29efea6808c1b7d580889bfd38f897d9e1c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Oct 2021 07:42:44 -0400
+Subject: sctp: fix the processing for COOKIE_ECHO chunk
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ 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 <lucien.xin@gmail.com>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..45a70f7
--- /dev/null
@@ -0,0 +1,135 @@
+From 0a9f0ecac2638bfc76addfa86810e0a81e1a9556 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Oct 2021 07:42:43 -0400
+Subject: sctp: fix the processing for INIT_ACK chunk
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ 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 <lucien.xin@gmail.com>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..bf917c4
--- /dev/null
@@ -0,0 +1,42 @@
+From b875c49bb4345c57d7acb715bd14647ca5e31d81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Oct 2021 07:42:41 -0400
+Subject: sctp: use init_tag from inithdr for ABORT chunk
+
+From: Xin Long <lucien.xin@gmail.com>
+
+[ 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 <lucien.xin@gmail.com>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
index fe3785c02e2fe33a23c9f5a359e06849af1027a2..b2f2ce9407b50d7b810a79de3af42d064575b685 100644 (file)
@@ -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