svn commit: r350508 - head/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Thu Aug 1 17:36:16 UTC 2019
Author: tuexen
Date: Thu Aug 1 17:36:15 2019
New Revision: 350508
URL: https://svnweb.freebsd.org/changeset/base/350508
Log:
When responding with an ABORT to an INIT chunk containing a
HOSTNAME parameter or a parameter with an illegal length, only
include an error cause indicating why the ABORT was sent.
This also fixes an mbuf leak which could occur.
MFC after: 3 days
Modified:
head/sys/netinet/sctp_output.c
Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c Thu Aug 1 17:28:36 2019 (r350507)
+++ head/sys/netinet/sctp_output.c Thu Aug 1 17:36:15 2019 (r350508)
@@ -5115,55 +5115,42 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_
break;
case SCTP_HOSTNAME_ADDRESS:
{
- /* We can NOT handle HOST NAME addresses!! */
+ /* Hostname parameters are deprecated. */
+ struct sctp_gen_error_cause *cause;
int l_len;
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Can't handle hostname addresses.. abort processing\n");
*abort_processing = 1;
- if (op_err == NULL) {
- /* Ok need to try to get a mbuf */
+ sctp_m_freem(op_err);
+ op_err = NULL;
#ifdef INET6
- l_len = SCTP_MIN_OVERHEAD;
+ l_len = SCTP_MIN_OVERHEAD;
#else
- l_len = SCTP_MIN_V4_OVERHEAD;
+ l_len = SCTP_MIN_V4_OVERHEAD;
#endif
- l_len += sizeof(struct sctp_chunkhdr);
- 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,
- * SCTP, and chunk header.
- */
+ l_len += sizeof(struct sctp_chunkhdr);
+ 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) {
+ /*
+ * Pre-reserve space for IP, SCTP,
+ * and chunk header.
+ */
#ifdef INET6
- SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
#else
- SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
#endif
- SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
- SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
- }
- }
- if (op_err) {
- /* If we have space */
- struct sctp_gen_error_cause cause;
-
- if (err_at % 4) {
- uint32_t cpthis = 0;
-
- pad_needed = 4 - (err_at % 4);
- m_copyback(op_err, err_at, pad_needed, (caddr_t)&cpthis);
- err_at += pad_needed;
- }
- 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_RESV_UF(op_err, sizeof(struct sctphdr));
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
+ SCTP_BUF_LEN(op_err) = sizeof(struct sctp_gen_error_cause);
+ cause = mtod(op_err, struct sctp_gen_error_cause *);
+ cause->code = htons(SCTP_CAUSE_UNRESOLVABLE_ADDR);
+ cause->length = htons((uint16_t)(sizeof(struct sctp_gen_error_cause) + plen));
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);
- return (NULL);
+ op_err = NULL;
}
}
return (op_err);
@@ -5250,7 +5237,10 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_
invalid_size:
SCTPDBG(SCTP_DEBUG_OUTPUT1, "abort flag set\n");
*abort_processing = 1;
- if ((op_err == NULL) && phdr) {
+ sctp_m_freem(op_err);
+ op_err = NULL;
+ if (phdr != NULL) {
+ struct sctp_paramhdr *param;
int l_len;
#ifdef INET6
l_len = SCTP_MIN_OVERHEAD;
@@ -5269,24 +5259,14 @@ invalid_size:
#endif
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
+ SCTP_BUF_LEN(op_err) = 2 * sizeof(struct sctp_paramhdr);
+ param = mtod(op_err, struct sctp_paramhdr *);
+ param->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
+ param->param_length = htons(2 * sizeof(struct sctp_paramhdr));
+ param++;
+ param->param_type = htons(ptype);
+ param->param_length = htons(plen);
}
- }
- if ((op_err) && phdr) {
- struct sctp_paramhdr s;
-
- if (err_at % 4) {
- uint32_t cpthis = 0;
-
- pad_needed = 4 - (err_at % 4);
- m_copyback(op_err, err_at, pad_needed, (caddr_t)&cpthis);
- err_at += pad_needed;
- }
- s.param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
- s.param_length = htons(sizeof(s) + sizeof(struct sctp_paramhdr));
- m_copyback(op_err, err_at, sizeof(s), (caddr_t)&s);
- err_at += sizeof(s);
- /* Only copy back the p-hdr that caused the issue */
- m_copyback(op_err, err_at, sizeof(struct sctp_paramhdr), (caddr_t)phdr);
}
return (op_err);
}
More information about the svn-src-head
mailing list