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
This commit is contained in:
Michael Tuexen 2012-04-19 12:43:19 +00:00
parent fc1de96060
commit 921569e288
2 changed files with 20 additions and 15 deletions

View File

@ -2746,11 +2746,13 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
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);
}

View File

@ -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);
}