svn commit: r264679 - head/sys/netinet

Michael Tuexen tuexen at FreeBSD.org
Sat Apr 19 19:21:07 UTC 2014


Author: tuexen
Date: Sat Apr 19 19:21:06 2014
New Revision: 264679
URL: http://svnweb.freebsd.org/changeset/base/264679

Log:
  Send the correct error cause, when a DATA chunk with no user data
  is received. This bug was reported by Irene Ruengeler.
  
  MFC after: 3 days

Modified:
  head/sys/netinet/sctp.h
  head/sys/netinet/sctp_indata.c
  head/sys/netinet/sctputil.c
  head/sys/netinet/sctputil.h

Modified: head/sys/netinet/sctp.h
==============================================================================
--- head/sys/netinet/sctp.h	Sat Apr 19 19:08:08 2014	(r264678)
+++ head/sys/netinet/sctp.h	Sat Apr 19 19:21:06 2014	(r264679)
@@ -408,6 +408,11 @@ struct sctp_error_unrecognized_chunk {
 	struct sctp_chunkhdr ch;/* header from chunk in error */
 }                             SCTP_PACKED;
 
+struct sctp_error_no_user_data {
+	struct sctp_error_cause cause;	/* code=SCTP_CAUSE_NO_USER_DATA */
+	uint32_t tsn;		/* TSN of the empty data chunk */
+}                       SCTP_PACKED;
+
 /*
  * Main SCTP chunk types we place these here so natd and f/w's in user land
  * can find them.

Modified: head/sys/netinet/sctp_indata.c
==============================================================================
--- head/sys/netinet/sctp_indata.c	Sat Apr 19 19:08:08 2014	(r264678)
+++ head/sys/netinet/sctp_indata.c	Sat Apr 19 19:21:06 2014	(r264679)
@@ -2323,7 +2323,7 @@ sctp_process_data(struct mbuf **mm, int 
 			continue;
 		}
 		if (ch->ch.chunk_type == SCTP_DATA) {
-			if ((size_t)chk_length < sizeof(struct sctp_data_chunk) + 1) {
+			if ((size_t)chk_length < sizeof(struct sctp_data_chunk)) {
 				/*
 				 * Need to send an abort since we had a
 				 * invalid data chunk.
@@ -2341,6 +2341,21 @@ sctp_process_data(struct mbuf **mm, int 
 				    vrf_id, port);
 				return (2);
 			}
+			if ((size_t)chk_length == sizeof(struct sctp_data_chunk)) {
+				/*
+				 * Need to send an abort since we had an
+				 * empty data chunk.
+				 */
+				struct mbuf *op_err;
+
+				op_err = sctp_generate_no_user_data_cause(ch->dp.tsn);
+				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_19;
+				sctp_abort_association(inp, stcb, m, iphlen,
+				    src, dst, sh, op_err,
+				    use_mflowid, mflowid,
+				    vrf_id, port);
+				return (2);
+			}
 #ifdef SCTP_AUDITING_ENABLED
 			sctp_audit_log(0xB1, 0);
 #endif

Modified: head/sys/netinet/sctputil.c
==============================================================================
--- head/sys/netinet/sctputil.c	Sat Apr 19 19:08:08 2014	(r264678)
+++ head/sys/netinet/sctputil.c	Sat Apr 19 19:21:06 2014	(r264679)
@@ -4654,6 +4654,25 @@ sctp_generate_cause(uint16_t code, char 
 	return (m);
 }
 
+struct mbuf *
+sctp_generate_no_user_data_cause(uint32_t tsn)
+{
+	struct mbuf *m;
+	struct sctp_error_no_user_data *no_user_data_cause;
+	size_t len;
+
+	len = sizeof(struct sctp_error_no_user_data);
+	m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
+	if (m != NULL) {
+		SCTP_BUF_LEN(m) = len;
+		no_user_data_cause = mtod(m, struct sctp_error_no_user_data *);
+		no_user_data_cause->cause.code = htons(SCTP_CAUSE_NO_USER_DATA);
+		no_user_data_cause->cause.length = htons((uint16_t) len);
+		no_user_data_cause->tsn = tsn;	/* tsn is passed in as NBO */
+	}
+	return (m);
+}
+
 #ifdef SCTP_MBCNT_LOGGING
 void
 sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc,

Modified: head/sys/netinet/sctputil.h
==============================================================================
--- head/sys/netinet/sctputil.h	Sat Apr 19 19:08:08 2014	(r264678)
+++ head/sys/netinet/sctputil.h	Sat Apr 19 19:21:06 2014	(r264679)
@@ -254,6 +254,7 @@ sctp_release_pr_sctp_chunk(struct sctp_t
 );
 
 struct mbuf *sctp_generate_cause(uint16_t, char *);
+struct mbuf *sctp_generate_no_user_data_cause(uint32_t);
 
 void 
 sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,


More information about the svn-src-head mailing list