Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 7 Apr 2018 19:58:14 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r332214 - stable/11/sys/netinet
Message-ID:  <201804071958.w37JwERH072329@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Sat Apr  7 19:58:14 2018
New Revision: 332214
URL: https://svnweb.freebsd.org/changeset/base/332214

Log:
  MFC r324729:
  
  Abort an SCTP association, when a DATA chunk is followed by an unknown
  chunk with a length smaller than the minimum length.
  
  Thanks to Felix Weinrank for making me aware of the problem.

Modified:
  stable/11/sys/netinet/sctp_indata.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/netinet/sctp_indata.c
==============================================================================
--- stable/11/sys/netinet/sctp_indata.c	Sat Apr  7 19:56:34 2018	(r332213)
+++ stable/11/sys/netinet/sctp_indata.c	Sat Apr  7 19:58:14 2018	(r332214)
@@ -2696,7 +2696,8 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *o
 	}
 	/* get pointer to the first chunk header */
 	ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
-	    sizeof(struct sctp_chunkhdr), (uint8_t *)&chunk_buf);
+	    sizeof(struct sctp_chunkhdr),
+	    (uint8_t *)&chunk_buf);
 	if (ch == NULL) {
 		return (1);
 	}
@@ -2753,7 +2754,8 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *o
 				struct mbuf *op_err;
 				char msg[SCTP_DIAG_INFO_LEN];
 
-				snprintf(msg, sizeof(msg), "DATA chunk of length %d",
+				snprintf(msg, sizeof(msg), "%s chunk of length %d",
+				    ch->chunk_type == SCTP_DATA ? "DATA" : "I-DATA",
 				    chk_length);
 				op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_20;
@@ -2830,7 +2832,25 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *o
 					return (2);
 				}
 			default:
-				/* unknown chunk type, use bit rules */
+				/*
+				 * Unknown chunk type: use bit rules after
+				 * checking length
+				 */
+				if (chk_length < sizeof(struct sctp_chunkhdr)) {
+					/*
+					 * Need to send an abort since we
+					 * had a invalid chunk.
+					 */
+					struct mbuf *op_err;
+					char msg[SCTP_DIAG_INFO_LEN];
+
+					snprintf(msg, sizeof(msg), "Chunk of length %d",
+					    chk_length);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
+					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_20;
+					sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
+					return (2);
+				}
 				if (ch->chunk_type & 0x40) {
 					/* Add a error report to the queue */
 					struct mbuf *op_err;
@@ -2866,7 +2886,8 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *o
 			continue;
 		}
 		ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
-		    sizeof(struct sctp_chunkhdr), (uint8_t *)&chunk_buf);
+		    sizeof(struct sctp_chunkhdr),
+		    (uint8_t *)&chunk_buf);
 		if (ch == NULL) {
 			*offset = length;
 			stop_proc = 1;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201804071958.w37JwERH072329>