From ed67dea7a460472062359f8f84e3d9e27e0becdd Mon Sep 17 00:00:00 2001 From: tuexen Date: Sun, 12 Oct 2014 17:45:22 +0000 Subject: MFC r272841: Ensure that the flags field of sctp_tmit_chunks is initialized. Thanks to Peter Bostroem from Google for reporting the issue. --- sys/netinet/sctp_input.c | 2 ++ sys/netinet/sctp_output.c | 51 +++++++++++++++++++++++++---------------------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 729c2c7..2a0387a 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -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); diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 7cbb30f..265be3e 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -8925,16 +8925,11 @@ sctp_queue_op_err(struct sctp_tcb *stcb, struct mbuf *op_err) 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; @@ -9022,12 +9017,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; @@ -9090,12 +9085,12 @@ sctp_send_heartbeat_ack(struct sctp_tcb *stcb, 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; @@ -9127,12 +9122,12 @@ sctp_send_cookie_ack(struct sctp_tcb *stcb) 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) { @@ -9173,9 +9168,10 @@ sctp_send_shutdown_ack(struct sctp_tcb *stcb, struct sctp_nets *net) 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; @@ -9216,9 +9212,10 @@ sctp_send_shutdown(struct sctp_tcb *stcb, struct sctp_nets *net) 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; @@ -9269,13 +9266,13 @@ sctp_send_asconf(struct sctp_tcb *stcb, struct sctp_nets *net, int addr_locked) 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) { @@ -9364,7 +9361,9 @@ sctp_send_asconf_ack(struct sctp_tcb *stcb) 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); @@ -9373,11 +9372,8 @@ sctp_send_asconf_ack(struct sctp_tcb *stcb) 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); @@ -10257,6 +10253,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); @@ -10490,6 +10487,7 @@ sctp_send_sack(struct sctp_tcb *stcb, int so_locked /* 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 */ @@ -11267,6 +11265,7 @@ sctp_send_hb(struct sctp_tcb *stcb, struct sctp_nets *net, int so_locked 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); @@ -11368,10 +11367,11 @@ sctp_send_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net, 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); @@ -11431,6 +11431,9 @@ sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net, 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. */ @@ -11517,8 +11520,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); @@ -11584,6 +11585,7 @@ sctp_send_cwr(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn, u 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); @@ -11895,6 +11897,7 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb, 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); -- cgit v1.1