Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Oct 2017 20:17:45 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r324729 - head/sys/netinet
Message-ID:  <201710182017.v9IKHjKh026043@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Wed Oct 18 20:17:44 2017
New Revision: 324729
URL: https://svnweb.freebsd.org/changeset/base/324729

Log:
  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.
  MFC after:	3 days

Modified:
  head/sys/netinet/sctp_indata.c

Modified: head/sys/netinet/sctp_indata.c
==============================================================================
--- head/sys/netinet/sctp_indata.c	Wed Oct 18 19:28:28 2017	(r324728)
+++ head/sys/netinet/sctp_indata.c	Wed Oct 18 20:17:44 2017	(r324729)
@@ -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?201710182017.v9IKHjKh026043>