Cleanup sctp_asconf_error_response() and ensure that the parameter
is padded as required. This fixes the followig bug reported by OSS-Fuzz for the usersctp stack: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17790 MFC after: 3 days
This commit is contained in:
parent
123d18b5c7
commit
5989470c37
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=353069
@ -105,42 +105,47 @@ sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t *error_tlv,
|
||||
struct mbuf *m_reply = NULL;
|
||||
struct sctp_asconf_paramhdr *aph;
|
||||
struct sctp_error_cause *error;
|
||||
size_t buf_len;
|
||||
uint16_t i, param_length, cause_length, padding_length;
|
||||
uint8_t *tlv;
|
||||
|
||||
m_reply = sctp_get_mbuf_for_msg((sizeof(struct sctp_asconf_paramhdr) +
|
||||
tlv_length +
|
||||
sizeof(struct sctp_error_cause)),
|
||||
0, M_NOWAIT, 1, MT_DATA);
|
||||
if (error_tlv == NULL) {
|
||||
tlv_length = 0;
|
||||
}
|
||||
cause_length = sizeof(struct sctp_error_cause) + tlv_length;
|
||||
param_length = sizeof(struct sctp_asconf_paramhdr) + cause_length;
|
||||
padding_length = tlv_length % 4;
|
||||
if (padding_length != 0) {
|
||||
padding_length = 4 - padding_length;
|
||||
}
|
||||
buf_len = param_length + padding_length;
|
||||
if (buf_len > MLEN) {
|
||||
SCTPDBG(SCTP_DEBUG_ASCONF1,
|
||||
"asconf_error_response: tlv_length (%xh) too big\n",
|
||||
tlv_length);
|
||||
return (NULL);
|
||||
}
|
||||
m_reply = sctp_get_mbuf_for_msg(buf_len, 0, M_NOWAIT, 1, MT_DATA);
|
||||
if (m_reply == NULL) {
|
||||
SCTPDBG(SCTP_DEBUG_ASCONF1,
|
||||
"asconf_error_response: couldn't get mbuf!\n");
|
||||
return (NULL);
|
||||
}
|
||||
aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
|
||||
error = (struct sctp_error_cause *)(aph + 1);
|
||||
|
||||
aph->correlation_id = id;
|
||||
aph->ph.param_type = htons(SCTP_ERROR_CAUSE_IND);
|
||||
aph->ph.param_length = htons(param_length);
|
||||
aph->correlation_id = id;
|
||||
error = (struct sctp_error_cause *)(aph + 1);
|
||||
error->code = htons(cause);
|
||||
error->length = tlv_length + sizeof(struct sctp_error_cause);
|
||||
aph->ph.param_length = error->length +
|
||||
sizeof(struct sctp_asconf_paramhdr);
|
||||
|
||||
if (aph->ph.param_length > MLEN) {
|
||||
SCTPDBG(SCTP_DEBUG_ASCONF1,
|
||||
"asconf_error_response: tlv_length (%xh) too big\n",
|
||||
tlv_length);
|
||||
sctp_m_freem(m_reply); /* discard */
|
||||
return (NULL);
|
||||
}
|
||||
error->length = htons(cause_length);
|
||||
if (error_tlv != NULL) {
|
||||
tlv = (uint8_t *)(error + 1);
|
||||
memcpy(tlv, error_tlv, tlv_length);
|
||||
for (i = 0; i < padding_length; i++) {
|
||||
tlv[tlv_length + i] = 0;
|
||||
}
|
||||
}
|
||||
SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
|
||||
error->length = htons(error->length);
|
||||
aph->ph.param_length = htons(aph->ph.param_length);
|
||||
|
||||
SCTP_BUF_LEN(m_reply) = buf_len;
|
||||
return (m_reply);
|
||||
}
|
||||
|
||||
@ -780,8 +785,6 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
|
||||
if (m_result != NULL) {
|
||||
SCTP_BUF_NEXT(m_tail) = m_result;
|
||||
m_tail = m_result;
|
||||
/* update lengths, make sure it's aligned too */
|
||||
SCTP_BUF_LEN(m_result) = SCTP_SIZE32(SCTP_BUF_LEN(m_result));
|
||||
ack_cp->ch.chunk_length += SCTP_BUF_LEN(m_result);
|
||||
/* set flag to force success reports */
|
||||
error = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user