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>