svn commit: r294157 - stable/10/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Sat Jan 16 16:42:42 UTC 2016
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++;
}
More information about the svn-src-stable-10
mailing list