From owner-svn-src-all@FreeBSD.ORG Thu Apr 19 12:43:20 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id BC93B1065673; Thu, 19 Apr 2012 12:43:20 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 8E21A8FC0C; Thu, 19 Apr 2012 12:43:20 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q3JChKVW089308; Thu, 19 Apr 2012 12:43:20 GMT (envelope-from tuexen@svn.freebsd.org) Received: (from tuexen@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q3JChKR4089305; Thu, 19 Apr 2012 12:43:20 GMT (envelope-from tuexen@svn.freebsd.org) Message-Id: <201204191243.q3JChKR4089305@svn.freebsd.org> From: Michael Tuexen Date: Thu, 19 Apr 2012 12:43:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r234459 - head/sys/netinet X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Apr 2012 12:43:20 -0000 Author: tuexen Date: Thu Apr 19 12:43:19 2012 New Revision: 234459 URL: http://svn.freebsd.org/changeset/base/234459 Log: Fix a bug where we copy out more data from a mbuf chain that are actually in it. This happens when SCTP receives an unknown chunk, which requires the sending of an ERROR chunk, and there is no final padding but the chunk is not 4-byte aligned. Reported by yueting via rwatson@ MFC after: 3 days Modified: head/sys/netinet/sctp_indata.c head/sys/netinet/sctp_input.c Modified: head/sys/netinet/sctp_indata.c ============================================================================== --- head/sys/netinet/sctp_indata.c Thu Apr 19 12:30:12 2012 (r234458) +++ head/sys/netinet/sctp_indata.c Thu Apr 19 12:43:19 2012 (r234459) @@ -2746,11 +2746,13 @@ sctp_process_data(struct mbuf **mm, int phd->param_length = htons(chk_length + sizeof(*phd)); SCTP_BUF_LEN(merr) = sizeof(*phd); - SCTP_BUF_NEXT(merr) = SCTP_M_COPYM(m, *offset, - SCTP_SIZE32(chk_length), - M_DONTWAIT); + SCTP_BUF_NEXT(merr) = SCTP_M_COPYM(m, *offset, chk_length, M_DONTWAIT); if (SCTP_BUF_NEXT(merr)) { - sctp_queue_op_err(stcb, merr); + if (sctp_pad_lastmbuf(SCTP_BUF_NEXT(merr), SCTP_SIZE32(chk_length) - chk_length, NULL)) { + sctp_m_freem(merr); + } else { + sctp_queue_op_err(stcb, merr); + } } else { sctp_m_freem(merr); } Modified: head/sys/netinet/sctp_input.c ============================================================================== --- head/sys/netinet/sctp_input.c Thu Apr 19 12:30:12 2012 (r234458) +++ head/sys/netinet/sctp_input.c Thu Apr 19 12:43:19 2012 (r234459) @@ -5461,23 +5461,26 @@ process_control_chunks: phd->param_type = htons(SCTP_CAUSE_UNRECOG_CHUNK); phd->param_length = htons(chk_length + sizeof(*phd)); SCTP_BUF_LEN(mm) = sizeof(*phd); - SCTP_BUF_NEXT(mm) = SCTP_M_COPYM(m, *offset, SCTP_SIZE32(chk_length), - M_DONTWAIT); + SCTP_BUF_NEXT(mm) = SCTP_M_COPYM(m, *offset, chk_length, M_DONTWAIT); if (SCTP_BUF_NEXT(mm)) { + if (sctp_pad_lastmbuf(SCTP_BUF_NEXT(mm), SCTP_SIZE32(chk_length) - chk_length, NULL)) { + sctp_m_freem(mm); + } else { #ifdef SCTP_MBUF_LOGGING - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) { - struct mbuf *mat; + if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) { + struct mbuf *mat; - mat = SCTP_BUF_NEXT(mm); - while (mat) { - if (SCTP_BUF_IS_EXTENDED(mat)) { - sctp_log_mb(mat, SCTP_MBUF_ICOPY); + mat = SCTP_BUF_NEXT(mm); + while (mat) { + if (SCTP_BUF_IS_EXTENDED(mat)) { + sctp_log_mb(mat, SCTP_MBUF_ICOPY); + } + mat = SCTP_BUF_NEXT(mat); } - mat = SCTP_BUF_NEXT(mat); } - } #endif - sctp_queue_op_err(stcb, mm); + sctp_queue_op_err(stcb, mm); + } } else { sctp_m_freem(mm); }