Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Aug 2016 17:19:33 +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: r303927 - head/sys/netinet
Message-ID:  <201608101719.u7AHJXYI056918@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Wed Aug 10 17:19:33 2016
New Revision: 303927
URL: https://svnweb.freebsd.org/changeset/base/303927

Log:
  Improve a consistency check to not detect valid cases for
  unordered user messages using DATA chunks as invalid ones.
  While there, ensure that error causes are provided when
  sending ABORT chunks in case of reassembly problems detected.
  Thanks to Taylor Brandstetter for making me aware of this 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 Aug 10 17:11:12 2016	(r303926)
+++ head/sys/netinet/sctp_indata.c	Wed Aug 10 17:19:33 2016	(r303927)
@@ -1747,21 +1747,27 @@ sctp_process_a_data_chunk(struct sctp_tc
 	 * If its a fragmented message, lets see if we can find the control
 	 * on the reassembly queues.
 	 */
-	if ((chtype == SCTP_IDATA) && ((chunk_flags & SCTP_DATA_FIRST_FRAG) == 0) && (fsn == 0)) {
+	if ((chtype == SCTP_IDATA) &&
+	    ((chunk_flags & SCTP_DATA_FIRST_FRAG) == 0) &&
+	    (fsn == 0)) {
 		/*
 		 * The first *must* be fsn 0, and other (middle/end) pieces
-		 * can *not* be fsn 0.
+		 * can *not* be fsn 0. XXX: This can happen in case of a
+		 * wrap around. Ignore is for now.
 		 */
+		snprintf(msg, sizeof(msg), "FSN zero for MID=%8.8x, but flags=%2.2x",
+		    msg_id, chunk_flags);
 		goto err_out;
 	}
+	control = sctp_find_reasm_entry(strm, msg_id, ordered, old_data);
+	SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags:0x%x look for control on queues %p\n",
+	    chunk_flags, control);
 	if ((chunk_flags & SCTP_DATA_NOT_FRAG) != SCTP_DATA_NOT_FRAG) {
 		/* See if we can find the re-assembly entity */
-		control = sctp_find_reasm_entry(strm, msg_id, ordered, old_data);
-		SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags:0x%x look for control on queues %p\n",
-		    chunk_flags, control);
-		if (control) {
+		if (control != NULL) {
 			/* We found something, does it belong? */
 			if (ordered && (msg_id != control->sinfo_ssn)) {
+				snprintf(msg, sizeof(msg), "Reassembly problem (MID=%8.8x)", msg_id);
 		err_out:
 				op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_15;
@@ -1774,6 +1780,8 @@ sctp_process_a_data_chunk(struct sctp_tc
 				 * We can't have a switched order with an
 				 * unordered chunk
 				 */
+				snprintf(msg, sizeof(msg), "All fragments of a user message must be ordered or unordered (TSN=%8.8x)",
+				    tsn);
 				goto err_out;
 			}
 			if (!ordered && (((control->sinfo_flags >> 8) & SCTP_DATA_UNORDERED) == 0)) {
@@ -1781,6 +1789,8 @@ sctp_process_a_data_chunk(struct sctp_tc
 				 * We can't have a switched unordered with a
 				 * ordered chunk
 				 */
+				snprintf(msg, sizeof(msg), "All fragments of a user message must be ordered or unordered (TSN=%8.8x)",
+				    tsn);
 				goto err_out;
 			}
 		}
@@ -1790,14 +1800,21 @@ sctp_process_a_data_chunk(struct sctp_tc
 		 * re-assembly going on with the same Stream/Seq (for
 		 * ordered) or in the same Stream for unordered.
 		 */
-		SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags:0x%x look for msg in case we have dup\n",
-		    chunk_flags);
-		if (sctp_find_reasm_entry(strm, msg_id, ordered, old_data)) {
-			SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags: 0x%x dup detected on msg_id: %u\n",
-			    chunk_flags,
-			    msg_id);
-
-			goto err_out;
+		if (control != NULL) {
+			if (ordered || (old_data == 0)) {
+				SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags: 0x%x dup detected on msg_id: %u\n",
+				    chunk_flags, msg_id);
+				snprintf(msg, sizeof(msg), "Duplicate MID=%8.8x detected.", msg_id);
+				goto err_out;
+			} else {
+				if ((tsn == control->fsn_included + 1) &&
+				    (control->end_added == 0)) {
+					snprintf(msg, sizeof(msg), "Illegal message sequence, missing end for MID: %8.8x", control->fsn_included);
+					goto err_out;
+				} else {
+					control = NULL;
+				}
+			}
 		}
 	}
 	/* now do the tests */



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