]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 Mar 2022 14:25:33 +0000 (15:25 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 Mar 2022 14:25:33 +0000 (15:25 +0100)
added patches:
sctp-fix-the-processing-for-init-chunk.patch

queue-5.4/sctp-fix-the-processing-for-init-chunk.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/sctp-fix-the-processing-for-init-chunk.patch b/queue-5.4/sctp-fix-the-processing-for-init-chunk.patch
new file mode 100644 (file)
index 0000000..a1c0e7d
--- /dev/null
@@ -0,0 +1,161 @@
+From eae5783908042a762c24e1bd11876edb91d314b1 Mon Sep 17 00:00:00 2001
+From: Xin Long <lucien.xin@gmail.com>
+Date: Wed, 20 Oct 2021 07:42:42 -0400
+Subject: sctp: fix the processing for INIT chunk
+
+From: Xin Long <lucien.xin@gmail.com>
+
+commit eae5783908042a762c24e1bd11876edb91d314b1 upstream.
+
+This patch fixes the problems below:
+
+1. In non-shutdown_ack_sent states: in sctp_sf_do_5_1B_init() and
+   sctp_sf_do_5_2_2_dupinit():
+
+  chunk length check should be done before any checks that may cause
+  to send abort, as making packet for abort will access the init_tag
+  from init_hdr in sctp_ootb_pkt_new().
+
+2. In shutdown_ack_sent state: in sctp_sf_do_9_2_reshutack():
+
+  The same checks as does in sctp_sf_do_5_2_2_dupinit() is needed
+  for sctp_sf_do_9_2_reshutack().
+
+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: Ovidiu Panait <ovidiu.panait@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/sm_statefuns.c |   71 +++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 46 insertions(+), 25 deletions(-)
+
+--- a/net/sctp/sm_statefuns.c
++++ b/net/sctp/sm_statefuns.c
+@@ -149,6 +149,12 @@ static enum sctp_disposition __sctp_sf_d
+                                       void *arg,
+                                       struct sctp_cmd_seq *commands);
++static enum sctp_disposition
++__sctp_sf_do_9_2_reshutack(struct net *net, const struct sctp_endpoint *ep,
++                         const struct sctp_association *asoc,
++                         const union sctp_subtype type, void *arg,
++                         struct sctp_cmd_seq *commands);
++
+ /* Small helper function that checks if the chunk length
+  * is of the appropriate length.  The 'required_length' argument
+  * is set to be the size of a specific chunk we are testing.
+@@ -330,6 +336,14 @@ enum sctp_disposition sctp_sf_do_5_1B_in
+       if (!chunk->singleton)
+               return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
++      /* Make sure that the INIT chunk has a valid length.
++       * Normally, this would cause an ABORT with a Protocol Violation
++       * error, but since we don't have an association, we'll
++       * just discard the packet.
++       */
++      if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_init_chunk)))
++              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.
+        */
+@@ -344,14 +358,6 @@ enum sctp_disposition sctp_sf_do_5_1B_in
+       if (chunk->sctp_hdr->vtag != 0)
+               return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
+-      /* Make sure that the INIT chunk has a valid length.
+-       * Normally, this would cause an ABORT with a Protocol Violation
+-       * error, but since we don't have an association, we'll
+-       * just discard the packet.
+-       */
+-      if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_init_chunk)))
+-              return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+-
+       /* If the INIT is coming toward a closing socket, we'll send back
+        * and ABORT.  Essentially, this catches the race of INIT being
+        * backloged to the socket at the same time as the user isses close().
+@@ -1484,19 +1490,16 @@ static enum sctp_disposition sctp_sf_do_
+       if (!chunk->singleton)
+               return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
++      /* Make sure that the INIT chunk has a valid length. */
++      if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_init_chunk)))
++              return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
++
+       /* 3.1 A packet containing an INIT chunk MUST have a zero Verification
+        * Tag.
+        */
+       if (chunk->sctp_hdr->vtag != 0)
+               return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
+-      /* Make sure that the INIT chunk has a valid length.
+-       * In this case, we generate a protocol violation since we have
+-       * an association established.
+-       */
+-      if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_init_chunk)))
+-              return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
+-                                                commands);
+       /* Grab the INIT header.  */
+       chunk->subh.init_hdr = (struct sctp_inithdr *)chunk->skb->data;
+@@ -1814,9 +1817,9 @@ static enum sctp_disposition sctp_sf_do_
+        * its peer.
+       */
+       if (sctp_state(asoc, SHUTDOWN_ACK_SENT)) {
+-              disposition = sctp_sf_do_9_2_reshutack(net, ep, asoc,
+-                              SCTP_ST_CHUNK(chunk->chunk_hdr->type),
+-                              chunk, commands);
++              disposition = __sctp_sf_do_9_2_reshutack(net, ep, asoc,
++                                                       SCTP_ST_CHUNK(chunk->chunk_hdr->type),
++                                                       chunk, commands);
+               if (SCTP_DISPOSITION_NOMEM == disposition)
+                       goto nomem;
+@@ -2915,13 +2918,11 @@ enum sctp_disposition sctp_sf_do_9_2_shu
+  * that belong to this association, it should discard the INIT chunk and
+  * retransmit the SHUTDOWN ACK chunk.
+  */
+-enum sctp_disposition sctp_sf_do_9_2_reshutack(
+-                                      struct net *net,
+-                                      const struct sctp_endpoint *ep,
+-                                      const struct sctp_association *asoc,
+-                                      const union sctp_subtype type,
+-                                      void *arg,
+-                                      struct sctp_cmd_seq *commands)
++static enum sctp_disposition
++__sctp_sf_do_9_2_reshutack(struct net *net, const struct sctp_endpoint *ep,
++                         const struct sctp_association *asoc,
++                         const union sctp_subtype type, void *arg,
++                         struct sctp_cmd_seq *commands)
+ {
+       struct sctp_chunk *chunk = arg;
+       struct sctp_chunk *reply;
+@@ -2955,6 +2956,26 @@ nomem:
+       return SCTP_DISPOSITION_NOMEM;
+ }
++enum sctp_disposition
++sctp_sf_do_9_2_reshutack(struct net *net, const struct sctp_endpoint *ep,
++                       const struct sctp_association *asoc,
++                       const union sctp_subtype type, void *arg,
++                       struct sctp_cmd_seq *commands)
++{
++      struct sctp_chunk *chunk = arg;
++
++      if (!chunk->singleton)
++              return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
++
++      if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_init_chunk)))
++              return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
++
++      if (chunk->sctp_hdr->vtag != 0)
++              return sctp_sf_tabort_8_4_8(net, ep, asoc, type, arg, commands);
++
++      return __sctp_sf_do_9_2_reshutack(net, ep, asoc, type, arg, commands);
++}
++
+ /*
+  * sctp_sf_do_ecn_cwr
+  *
index 8f5aea7fa8bc3a5c85135fd61cefe6b5dbe64976..a234b8229c861f7d84e3f48ffc85351a372c4254 100644 (file)
@@ -1 +1,2 @@
 revert-xfrm-state-and-policy-should-fail-if-xfrma_if_id-0.patch
+sctp-fix-the-processing-for-init-chunk.patch