From owner-svn-src-stable@freebsd.org Sat Jan 16 16:42:41 2016 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DC8A8A83EB1; Sat, 16 Jan 2016 16:42:41 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9BA88144F; Sat, 16 Jan 2016 16:42:41 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u0GGge6j029737; Sat, 16 Jan 2016 16:42:40 GMT (envelope-from tuexen@FreeBSD.org) Received: (from tuexen@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u0GGgeH4029733; Sat, 16 Jan 2016 16:42:40 GMT (envelope-from tuexen@FreeBSD.org) Message-Id: <201601161642.u0GGgeH4029733@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: tuexen set sender to tuexen@FreeBSD.org using -f From: Michael Tuexen Date: Sat, 16 Jan 2016 16:42:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r294157 - stable/10/sys/netinet X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Jan 2016 16:42:42 -0000 Author: tuexen Date: Sat Jan 16 16:42:40 2016 New Revision: 294157 URL: https://svnweb.freebsd.org/changeset/base/294157 Log: MFC r287669: Ensure that ERROR chunks are always padded by implementing this in the routine, which queues an ERROR chunk, instead on relyinh on the callers to do so. Since one caller missed this, this actially fixes a bug. Modified: stable/10/sys/netinet/sctp_constants.h stable/10/sys/netinet/sctp_indata.c stable/10/sys/netinet/sctp_input.c stable/10/sys/netinet/sctp_output.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/netinet/sctp_constants.h ============================================================================== --- stable/10/sys/netinet/sctp_constants.h Sat Jan 16 14:56:30 2016 (r294156) +++ stable/10/sys/netinet/sctp_constants.h Sat Jan 16 16:42:40 2016 (r294157) @@ -66,6 +66,8 @@ __FBSDID("$FreeBSD$"); */ #define SCTP_LARGEST_INIT_ACCEPTED (65535 - 2048) +/* Largest length of a chunk */ +#define SCTP_MAX_CHUNK_LENGTH 0xffff /* Number of addresses where we just skip the counting */ #define SCTP_COUNT_LIMIT 40 Modified: stable/10/sys/netinet/sctp_indata.c ============================================================================== --- stable/10/sys/netinet/sctp_indata.c Sat Jan 16 14:56:30 2016 (r294156) +++ stable/10/sys/netinet/sctp_indata.c Sat Jan 16 16:42:40 2016 (r294157) @@ -2513,11 +2513,7 @@ sctp_process_data(struct mbuf **mm, int SCTP_BUF_LEN(merr) = sizeof(*phd); SCTP_BUF_NEXT(merr) = SCTP_M_COPYM(m, *offset, chk_length, M_NOWAIT); if (SCTP_BUF_NEXT(merr)) { - if (sctp_pad_lastmbuf(SCTP_BUF_NEXT(merr), SCTP_SIZE32(chk_length) - chk_length, NULL) == NULL) { - sctp_m_freem(merr); - } else { - sctp_queue_op_err(stcb, merr); - } + sctp_queue_op_err(stcb, merr); } else { sctp_m_freem(merr); } Modified: stable/10/sys/netinet/sctp_input.c ============================================================================== --- stable/10/sys/netinet/sctp_input.c Sat Jan 16 14:56:30 2016 (r294156) +++ stable/10/sys/netinet/sctp_input.c Sat Jan 16 16:42:40 2016 (r294157) @@ -5602,16 +5602,12 @@ process_control_chunks: SCTP_BUF_LEN(mm) = sizeof(*phd); SCTP_BUF_NEXT(mm) = SCTP_M_COPYM(m, *offset, len, M_NOWAIT); if (SCTP_BUF_NEXT(mm)) { - if (sctp_pad_lastmbuf(SCTP_BUF_NEXT(mm), SCTP_SIZE32(len) - len, NULL) == NULL) { - sctp_m_freem(mm); - } else { #ifdef SCTP_MBUF_LOGGING - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) { - sctp_log_mbc(SCTP_BUF_NEXT(mm), SCTP_MBUF_ICOPY); - } -#endif - sctp_queue_op_err(stcb, mm); + if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) { + sctp_log_mbc(SCTP_BUF_NEXT(mm), SCTP_MBUF_ICOPY); } +#endif + sctp_queue_op_err(stcb, mm); } else { sctp_m_freem(mm); } Modified: stable/10/sys/netinet/sctp_output.c ============================================================================== --- stable/10/sys/netinet/sctp_output.c Sat Jan 16 14:56:30 2016 (r294156) +++ stable/10/sys/netinet/sctp_output.c Sat Jan 16 16:42:40 2016 (r294157) @@ -8866,9 +8866,37 @@ sctp_queue_op_err(struct sctp_tcb *stcb, */ struct sctp_chunkhdr *hdr; struct sctp_tmit_chunk *chk; - struct mbuf *mat; + struct mbuf *mat, *last_mbuf; + uint32_t chunk_length; + uint16_t padding_length; SCTP_TCB_LOCK_ASSERT(stcb); + SCTP_BUF_PREPEND(op_err, sizeof(struct sctp_chunkhdr), M_NOWAIT); + if (op_err == NULL) { + return; + } + last_mbuf = NULL; + chunk_length = 0; + for (mat = op_err; mat != NULL; mat = SCTP_BUF_NEXT(mat)) { + chunk_length += SCTP_BUF_LEN(mat); + if (SCTP_BUF_NEXT(mat) == NULL) { + last_mbuf = mat; + } + } + if (chunk_length > SCTP_MAX_CHUNK_LENGTH) { + sctp_m_freem(op_err); + return; + } + padding_length = chunk_length % 4; + if (padding_length != 0) { + padding_length = 4 - padding_length; + } + if (padding_length != 0) { + if (sctp_add_pad_tombuf(last_mbuf, padding_length) == NULL) { + sctp_m_freem(op_err); + return; + } + } sctp_alloc_a_chunk(stcb, chk); if (chk == NULL) { /* no memory */ @@ -8876,15 +8904,7 @@ sctp_queue_op_err(struct sctp_tcb *stcb, return; } chk->copy_by_ref = 0; - SCTP_BUF_PREPEND(op_err, sizeof(struct sctp_chunkhdr), M_NOWAIT); - if (op_err == NULL) { - sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); - return; - } - chk->send_size = 0; - for (mat = op_err; mat != NULL; mat = SCTP_BUF_NEXT(mat)) { - chk->send_size += SCTP_BUF_LEN(mat); - } + chk->send_size = (uint16_t) chunk_length; chk->sent = SCTP_DATAGRAM_UNSENT; chk->snd_count = 0; chk->asoc = &stcb->asoc; @@ -8894,9 +8914,7 @@ sctp_queue_op_err(struct sctp_tcb *stcb, hdr->chunk_type = SCTP_OPERATION_ERROR; hdr->chunk_flags = 0; hdr->chunk_length = htons(chk->send_size); - TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue, - chk, - sctp_next); + TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue, chk, sctp_next); chk->asoc->ctrl_queue_cnt++; }