summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_input.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2007-06-15 17:59:57 +0000
committerrrs <rrs@FreeBSD.org>2007-06-15 17:59:57 +0000
commit57b3f6ebdecb9baca61db7b79bd89926b5be6c2e (patch)
treea0242057ec0c3b373ca3da10937b024b87996162 /sys/netinet/sctp_input.c
parent6b110dc4737f233a6f6e37b1f2fafa7bdeee7520 (diff)
downloadFreeBSD-src-57b3f6ebdecb9baca61db7b79bd89926b5be6c2e.zip
FreeBSD-src-57b3f6ebdecb9baca61db7b79bd89926b5be6c2e.tar.gz
- Issue one, new stack reduction left packet_drop handling still
thinking it had the whole chunk. This could cause a crash if a large packet drop came in. Fixed by adjusting the trunc length down to the limit. - Large sacks with lots of segments could also have same issue. Changed duplicate and segment handling to use proper get_m_ptr function to pull each block from mbuf chains.
Diffstat (limited to 'sys/netinet/sctp_input.c')
-rw-r--r--sys/netinet/sctp_input.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 0baeaba..2578d9f 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -3177,7 +3177,7 @@ strres_nochunk:
*/
static void
sctp_handle_packet_dropped(struct sctp_pktdrop_chunk *cp,
- struct sctp_tcb *stcb, struct sctp_nets *net)
+ struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t limit)
{
uint32_t bottle_bw, on_queue;
uint16_t trunc_len;
@@ -3200,6 +3200,9 @@ sctp_handle_packet_dropped(struct sctp_pktdrop_chunk *cp,
memset(&desc, 0, sizeof(desc));
}
trunc_len = (uint16_t) ntohs(cp->trunc_len);
+ if (trunc_len > limit) {
+ trunc_len = limit;
+ }
/* now the chunks themselves */
while ((ch != NULL) && (chlen >= sizeof(struct sctp_chunkhdr))) {
desc.chunk_type = ch->chunk_type;
@@ -3889,7 +3892,8 @@ process_control_chunks:
&abort_now);
} else {
if (netp && *netp)
- sctp_handle_sack(sack, stcb, *netp, &abort_now, chk_length, a_rwnd);
+ sctp_handle_sack(m, *offset,
+ sack, stcb, *netp, &abort_now, chk_length, a_rwnd);
}
if (abort_now) {
/* ABORT signal from sack processing */
@@ -4233,8 +4237,6 @@ process_control_chunks:
break;
case SCTP_STREAM_RESET:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_STREAM_RESET\n");
- ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
- chk_length, chunk_buf);
if (((stcb == NULL) || (ch == NULL) || (chk_length < sizeof(struct sctp_stream_reset_tsn_req)))) {
/* Its not ours */
if (locked_tcb) {
@@ -4274,12 +4276,11 @@ process_control_chunks:
*offset = length;
return (NULL);
}
- ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
- chk_length, chunk_buf);
-
if (ch && (stcb) && netp && (*netp)) {
sctp_handle_packet_dropped((struct sctp_pktdrop_chunk *)ch,
- stcb, *netp);
+ stcb, *netp,
+ min(chk_length, (sizeof(chunk_buf) - 4)));
+
}
break;
@@ -4312,8 +4313,6 @@ process_control_chunks:
/* skip this chunk... it's already auth'd */
goto next_chunk;
}
- ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
- chk_length, chunk_buf);
got_auth = 1;
if ((ch == NULL) || sctp_handle_auth(stcb, (struct sctp_auth_chunk *)ch,
m, *offset)) {
OpenPOWER on IntegriCloud