svn commit: r273106 - releng/10.1/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Tue Oct 14 19:38:33 UTC 2014
Author: tuexen
Date: Tue Oct 14 19:38:31 2014
New Revision: 273106
URL: https://svnweb.freebsd.org/changeset/base/273106
Log:
MF10 r273000 (r272750 in head)
Ensure that the number of stream reported in srs_number_streams is
consistent with the amount of data provided in the SCTP_RESET_STREAMS
socket option.
Thanks to Peter Bostroem from Google for drawing my attention to
this part of the code.
MF10 r273001 (r272751 in head):
Ensure that the list of streams sent in a stream reset parameter fits
in an mbuf-cluster.
Thanks to Peter Bostroem for drawing my attention to this part of the code.
MF10 r273002 (r272841 in head):
Ensure that the flags field of sctp_tmit_chunks is initialized.
Thanks to Peter Bostroem from Google for reporting the issue.
Approved by: re (marius)
Modified:
releng/10.1/sys/netinet/sctp_input.c
releng/10.1/sys/netinet/sctp_output.c
releng/10.1/sys/netinet/sctp_output.h
releng/10.1/sys/netinet/sctp_usrreq.c
Directory Properties:
releng/10.1/ (props changed)
Modified: releng/10.1/sys/netinet/sctp_input.c
==============================================================================
--- releng/10.1/sys/netinet/sctp_input.c Tue Oct 14 19:21:04 2014 (r273105)
+++ releng/10.1/sys/netinet/sctp_input.c Tue Oct 14 19:38:31 2014 (r273106)
@@ -4069,8 +4069,10 @@ __attribute__((noinline))
if (chk == NULL) {
return (ret_code);
}
+ chk->copy_by_ref = 0;
chk->rec.chunk_id.id = SCTP_STREAM_RESET;
chk->rec.chunk_id.can_take_data = 0;
+ chk->flags = 0;
chk->asoc = &stcb->asoc;
chk->no_fr_allowed = 0;
chk->book_size = chk->send_size = sizeof(struct sctp_chunkhdr);
Modified: releng/10.1/sys/netinet/sctp_output.c
==============================================================================
--- releng/10.1/sys/netinet/sctp_output.c Tue Oct 14 19:21:04 2014 (r273105)
+++ releng/10.1/sys/netinet/sctp_output.c Tue Oct 14 19:38:31 2014 (r273106)
@@ -8932,16 +8932,11 @@ sctp_queue_op_err(struct sctp_tcb *stcb,
return;
}
chk->send_size = 0;
- mat = op_err;
- while (mat != NULL) {
+ for (mat = op_err; mat != NULL; mat = SCTP_BUF_NEXT(mat)) {
chk->send_size += SCTP_BUF_LEN(mat);
- mat = SCTP_BUF_NEXT(mat);
}
- chk->rec.chunk_id.id = SCTP_OPERATION_ERROR;
- chk->rec.chunk_id.can_take_data = 1;
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
- chk->flags = 0;
chk->asoc = &stcb->asoc;
chk->data = op_err;
chk->whoTo = NULL;
@@ -9029,12 +9024,12 @@ sctp_send_cookie_echo(struct mbuf *m,
return (-5);
}
chk->copy_by_ref = 0;
- chk->send_size = plen;
chk->rec.chunk_id.id = SCTP_COOKIE_ECHO;
chk->rec.chunk_id.can_take_data = 0;
+ chk->flags = CHUNK_FLAGS_FRAGMENT_OK;
+ chk->send_size = plen;
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
- chk->flags = CHUNK_FLAGS_FRAGMENT_OK;
chk->asoc = &stcb->asoc;
chk->data = cookie;
chk->whoTo = net;
@@ -9097,12 +9092,12 @@ sctp_send_heartbeat_ack(struct sctp_tcb
return;
}
chk->copy_by_ref = 0;
- chk->send_size = chk_length;
chk->rec.chunk_id.id = SCTP_HEARTBEAT_ACK;
chk->rec.chunk_id.can_take_data = 1;
+ chk->flags = 0;
+ chk->send_size = chk_length;
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
- chk->flags = 0;
chk->asoc = &stcb->asoc;
chk->data = outchain;
chk->whoTo = net;
@@ -9134,12 +9129,12 @@ sctp_send_cookie_ack(struct sctp_tcb *st
return;
}
chk->copy_by_ref = 0;
- chk->send_size = sizeof(struct sctp_chunkhdr);
chk->rec.chunk_id.id = SCTP_COOKIE_ACK;
chk->rec.chunk_id.can_take_data = 1;
+ chk->flags = 0;
+ chk->send_size = sizeof(struct sctp_chunkhdr);
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
- chk->flags = 0;
chk->asoc = &stcb->asoc;
chk->data = cookie_ack;
if (chk->asoc->last_control_chunk_from != NULL) {
@@ -9180,9 +9175,10 @@ sctp_send_shutdown_ack(struct sctp_tcb *
return;
}
chk->copy_by_ref = 0;
- chk->send_size = sizeof(struct sctp_chunkhdr);
chk->rec.chunk_id.id = SCTP_SHUTDOWN_ACK;
chk->rec.chunk_id.can_take_data = 1;
+ chk->flags = 0;
+ chk->send_size = sizeof(struct sctp_chunkhdr);
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
chk->flags = 0;
@@ -9223,9 +9219,10 @@ sctp_send_shutdown(struct sctp_tcb *stcb
return;
}
chk->copy_by_ref = 0;
- chk->send_size = sizeof(struct sctp_shutdown_chunk);
chk->rec.chunk_id.id = SCTP_SHUTDOWN;
chk->rec.chunk_id.can_take_data = 1;
+ chk->flags = 0;
+ chk->send_size = sizeof(struct sctp_shutdown_chunk);
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
chk->flags = 0;
@@ -9276,13 +9273,13 @@ sctp_send_asconf(struct sctp_tcb *stcb,
return;
}
chk->copy_by_ref = 0;
- chk->data = m_asconf;
- chk->send_size = len;
chk->rec.chunk_id.id = SCTP_ASCONF;
chk->rec.chunk_id.can_take_data = 0;
+ chk->flags = CHUNK_FLAGS_FRAGMENT_OK;
+ chk->data = m_asconf;
+ chk->send_size = len;
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
- chk->flags = CHUNK_FLAGS_FRAGMENT_OK;
chk->asoc = &stcb->asoc;
chk->whoTo = net;
if (chk->whoTo) {
@@ -9371,7 +9368,9 @@ sctp_send_asconf_ack(struct sctp_tcb *st
return;
}
chk->copy_by_ref = 0;
-
+ chk->rec.chunk_id.id = SCTP_ASCONF_ACK;
+ chk->rec.chunk_id.can_take_data = 1;
+ chk->flags = CHUNK_FLAGS_FRAGMENT_OK;
chk->whoTo = net;
if (chk->whoTo) {
atomic_add_int(&chk->whoTo->ref_count, 1);
@@ -9380,11 +9379,8 @@ sctp_send_asconf_ack(struct sctp_tcb *st
chk->send_size = 0;
/* Get size */
chk->send_size = ack->len;
- chk->rec.chunk_id.id = SCTP_ASCONF_ACK;
- chk->rec.chunk_id.can_take_data = 1;
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
- chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; /* XXX */
chk->asoc = &stcb->asoc;
TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue, chk, sctp_next);
@@ -10264,6 +10260,7 @@ send_forward_tsn(struct sctp_tcb *stcb,
chk->copy_by_ref = 0;
chk->rec.chunk_id.id = SCTP_FORWARD_CUM_TSN;
chk->rec.chunk_id.can_take_data = 0;
+ chk->flags = 0;
chk->asoc = asoc;
chk->whoTo = NULL;
chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
@@ -10497,6 +10494,7 @@ sctp_send_sack(struct sctp_tcb *stcb, in
/* Clear our pkt counts */
asoc->data_pkts_seen = 0;
+ a_chk->flags = 0;
a_chk->asoc = asoc;
a_chk->snd_count = 0;
a_chk->send_size = 0; /* fill in later */
@@ -11274,6 +11272,7 @@ sctp_send_hb(struct sctp_tcb *stcb, stru
chk->copy_by_ref = 0;
chk->rec.chunk_id.id = SCTP_HEARTBEAT_REQUEST;
chk->rec.chunk_id.can_take_data = 1;
+ chk->flags = 0;
chk->asoc = &stcb->asoc;
chk->send_size = sizeof(struct sctp_heartbeat_chunk);
@@ -11375,10 +11374,11 @@ sctp_send_ecn_echo(struct sctp_tcb *stcb
if (chk == NULL) {
return;
}
- chk->copy_by_ref = 0;
SCTP_STAT_INCR(sctps_queue_upd_ecne);
+ chk->copy_by_ref = 0;
chk->rec.chunk_id.id = SCTP_ECN_ECHO;
chk->rec.chunk_id.can_take_data = 0;
+ chk->flags = 0;
chk->asoc = &stcb->asoc;
chk->send_size = sizeof(struct sctp_ecne_chunk);
chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_NOWAIT, 1, MT_HEADER);
@@ -11438,6 +11438,9 @@ sctp_send_packet_dropped(struct sctp_tcb
return;
}
chk->copy_by_ref = 0;
+ chk->rec.chunk_id.id = SCTP_PACKET_DROPPED;
+ chk->rec.chunk_id.can_take_data = 1;
+ chk->flags = 0;
len -= iphlen;
chk->send_size = len;
/* Validate that we do not have an ABORT in here. */
@@ -11524,8 +11527,6 @@ jump_out:
} else {
chk->whoTo = NULL;
}
- chk->rec.chunk_id.id = SCTP_PACKET_DROPPED;
- chk->rec.chunk_id.can_take_data = 1;
drp->ch.chunk_type = SCTP_PACKET_DROPPED;
drp->ch.chunk_length = htons(chk->send_size);
spc = SCTP_SB_LIMIT_RCV(stcb->sctp_socket);
@@ -11591,6 +11592,7 @@ sctp_send_cwr(struct sctp_tcb *stcb, str
chk->copy_by_ref = 0;
chk->rec.chunk_id.id = SCTP_ECN_CWR;
chk->rec.chunk_id.can_take_data = 1;
+ chk->flags = 0;
chk->asoc = &stcb->asoc;
chk->send_size = sizeof(struct sctp_cwr_chunk);
chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_NOWAIT, 1, MT_HEADER);
@@ -11853,7 +11855,7 @@ sctp_add_an_in_stream(struct sctp_tmit_c
int
sctp_send_str_reset_req(struct sctp_tcb *stcb,
- int number_entries, uint16_t * list,
+ uint16_t number_entries, uint16_t * list,
uint8_t send_out_req,
uint8_t send_in_req,
uint8_t send_tsn_req,
@@ -11886,6 +11888,14 @@ sctp_send_str_reset_req(struct sctp_tcb
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EINVAL);
return (EINVAL);
}
+ if (number_entries > (MCLBYTES -
+ SCTP_MIN_OVERHEAD -
+ sizeof(struct sctp_chunkhdr) -
+ sizeof(struct sctp_stream_reset_out_request)) /
+ sizeof(uint16_t)) {
+ SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
+ return (ENOMEM);
+ }
sctp_alloc_a_chunk(stcb, chk);
if (chk == NULL) {
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
@@ -11894,6 +11904,7 @@ sctp_send_str_reset_req(struct sctp_tcb
chk->copy_by_ref = 0;
chk->rec.chunk_id.id = SCTP_STREAM_RESET;
chk->rec.chunk_id.can_take_data = 0;
+ chk->flags = 0;
chk->asoc = &stcb->asoc;
chk->book_size = sizeof(struct sctp_chunkhdr);
chk->send_size = SCTP_SIZE32(chk->book_size);
Modified: releng/10.1/sys/netinet/sctp_output.h
==============================================================================
--- releng/10.1/sys/netinet/sctp_output.h Tue Oct 14 19:21:04 2014 (r273105)
+++ releng/10.1/sys/netinet/sctp_output.h Tue Oct 14 19:38:31 2014 (r273106)
@@ -181,8 +181,8 @@ sctp_add_stream_reset_result_tsn(struct
uint32_t, uint32_t, uint32_t, uint32_t);
int
-sctp_send_str_reset_req(struct sctp_tcb *, int, uint16_t *, uint8_t, uint8_t,
- uint8_t, uint8_t, uint16_t, uint16_t, uint8_t);
+sctp_send_str_reset_req(struct sctp_tcb *, uint16_t, uint16_t *, uint8_t,
+ uint8_t, uint8_t, uint8_t, uint16_t, uint16_t, uint8_t);
void
sctp_send_abort(struct mbuf *, int, struct sockaddr *, struct sockaddr *,
Modified: releng/10.1/sys/netinet/sctp_usrreq.c
==============================================================================
--- releng/10.1/sys/netinet/sctp_usrreq.c Tue Oct 14 19:21:04 2014 (r273105)
+++ releng/10.1/sys/netinet/sctp_usrreq.c Tue Oct 14 19:38:31 2014 (r273106)
@@ -4431,6 +4431,12 @@ sctp_setopt(struct socket *so, int optna
SCTP_TCB_UNLOCK(stcb);
break;
}
+ if (sizeof(struct sctp_reset_streams) +
+ strrst->srs_number_streams * sizeof(uint16_t) > optsize) {
+ error = EINVAL;
+ SCTP_TCB_UNLOCK(stcb);
+ break;
+ }
if (stcb->asoc.stream_reset_outstanding) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
error = EALREADY;
More information about the svn-src-releng
mailing list