From 3535cdc43e07efefbe6993e2a835896fd8fdbdce Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sun, 7 Oct 2018 15:13:47 +0000 Subject: [PATCH] Avoid truncating unrecognised parameters when reporting them. This resulted in sending malformed packets. Approved by: re (kib@) MFC after: 1 week --- sys/netinet/sctp_output.c | 49 ++++++++++++--------------------------- 1 file changed, 15 insertions(+), 34 deletions(-) diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 34e91d8b0af..ddf5a4ddfd2 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -4983,7 +4983,6 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, struct sctp_paramhdr *phdr, params; struct mbuf *mat, *op_err; - char tempbuf[SCTP_PARAM_BUFFER_SIZE]; int at, limit, pad_needed; uint16_t ptype, plen, padded_size; int err_at; @@ -5123,15 +5122,13 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, l_len = SCTP_MIN_V4_OVERHEAD; #endif l_len += sizeof(struct sctp_chunkhdr); - l_len += plen; - l_len += sizeof(struct sctp_paramhdr); + l_len += sizeof(struct sctp_gen_error_cause); op_err = sctp_get_mbuf_for_msg(l_len, 0, M_NOWAIT, 1, MT_DATA); if (op_err) { SCTP_BUF_LEN(op_err) = 0; /* - * pre-reserve space for ip - * and sctp header and - * chunk hdr + * Pre-reserve space for IP, + * SCTP, and chunk header. */ #ifdef INET6 SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr)); @@ -5144,7 +5141,7 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, } if (op_err) { /* If we have space */ - struct sctp_paramhdr s; + struct sctp_gen_error_cause cause; if (err_at % 4) { uint32_t cpthis = 0; @@ -5153,26 +5150,15 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, m_copyback(op_err, err_at, pad_needed, (caddr_t)&cpthis); err_at += pad_needed; } - s.param_type = htons(SCTP_CAUSE_UNRESOLVABLE_ADDR); - s.param_length = htons(sizeof(s) + plen); - m_copyback(op_err, err_at, sizeof(s), (caddr_t)&s); - err_at += sizeof(s); - if (plen > sizeof(tempbuf)) { - plen = sizeof(tempbuf); - } - phdr = sctp_get_next_param(mat, at, (struct sctp_paramhdr *)tempbuf, plen); - if (phdr == NULL) { + cause.code = htons(SCTP_CAUSE_UNRESOLVABLE_ADDR); + cause.length = htons((uint16_t)(sizeof(struct sctp_gen_error_cause) + plen)); + m_copyback(op_err, err_at, sizeof(struct sctp_gen_error_cause), (caddr_t)&cause); + err_at += sizeof(struct sctp_gen_error_cause); + SCTP_BUF_NEXT(op_err) = SCTP_M_COPYM(mat, at, plen, M_NOWAIT); + if (SCTP_BUF_NEXT(op_err) == NULL) { sctp_m_freem(op_err); - /* - * we are out of memory but - * we still need to have a - * look at what to do (the - * system is in trouble - * though). - */ return (NULL); } - m_copyback(op_err, err_at, plen, (caddr_t)phdr); } return (op_err); break; @@ -5196,7 +5182,6 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, l_len = SCTP_MIN_V4_OVERHEAD; #endif l_len += sizeof(struct sctp_chunkhdr); - l_len += plen; l_len += sizeof(struct sctp_paramhdr); op_err = sctp_get_mbuf_for_msg(l_len, 0, M_NOWAIT, 1, MT_DATA); if (op_err) { @@ -5222,14 +5207,11 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, err_at += pad_needed; } s.param_type = htons(SCTP_UNRECOG_PARAM); - s.param_length = htons(sizeof(s) + plen); - m_copyback(op_err, err_at, sizeof(s), (caddr_t)&s); - err_at += sizeof(s); - if (plen > sizeof(tempbuf)) { - plen = sizeof(tempbuf); - } - phdr = sctp_get_next_param(mat, at, (struct sctp_paramhdr *)tempbuf, plen); - if (phdr == NULL) { + s.param_length = htons((uint16_t)sizeof(struct sctp_paramhdr) + plen); + m_copyback(op_err, err_at, sizeof(struct sctp_paramhdr), (caddr_t)&s); + err_at += sizeof(struct sctp_paramhdr); + SCTP_BUF_NEXT(op_err) = SCTP_M_COPYM(mat, at, plen, M_NOWAIT); + if (SCTP_BUF_NEXT(op_err) == NULL) { sctp_m_freem(op_err); /* * we are out of memory but @@ -5241,7 +5223,6 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, op_err = NULL; goto more_processing; } - m_copyback(op_err, err_at, plen, (caddr_t)phdr); err_at += plen; } } -- 2.45.0