aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/sctp_input.c
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2012-04-19 12:43:19 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2012-04-19 12:43:19 +0000
commit921569e288d4f61929640838d8ceb57b797e0884 (patch)
tree9c13f406a5f9af38a9f4b49f9732347046ec6112 /sys/netinet/sctp_input.c
parentfc1de96060db910b8aa5224d4d10b37baefeca1e (diff)
downloadsrc-921569e288d4f61929640838d8ceb57b797e0884.tar.gz
src-921569e288d4f61929640838d8ceb57b797e0884.zip
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
Notes
Notes: svn path=/head/; revision=234459
Diffstat (limited to 'sys/netinet/sctp_input.c')
-rw-r--r--sys/netinet/sctp_input.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 1f9ee89a3a1e..fe0e63665e67 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -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;
-
- mat = SCTP_BUF_NEXT(mm);
- while (mat) {
- if (SCTP_BUF_IS_EXTENDED(mat)) {
- sctp_log_mb(mat, SCTP_MBUF_ICOPY);
+ 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(mat);
}
- mat = SCTP_BUF_NEXT(mat);
}
- }
#endif
- sctp_queue_op_err(stcb, mm);
+ sctp_queue_op_err(stcb, mm);
+ }
} else {
sctp_m_freem(mm);
}