svn commit: r324729 - head/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Wed Oct 18 20:17:47 UTC 2017
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;
More information about the svn-src-head
mailing list