From owner-svn-src-all@FreeBSD.ORG Tue Oct 14 19:38:33 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id ADEC7C9E; Tue, 14 Oct 2014 19:38:33 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 890DCBCA; Tue, 14 Oct 2014 19:38:33 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s9EJcXIv016366; Tue, 14 Oct 2014 19:38:33 GMT (envelope-from tuexen@FreeBSD.org) Received: (from tuexen@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s9EJcW2d016362; Tue, 14 Oct 2014 19:38:32 GMT (envelope-from tuexen@FreeBSD.org) Message-Id: <201410141938.s9EJcW2d016362@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: tuexen set sender to tuexen@FreeBSD.org using -f From: Michael Tuexen Date: Tue, 14 Oct 2014 19:38:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org Subject: svn commit: r273106 - releng/10.1/sys/netinet X-SVN-Group: releng MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Oct 2014 19:38:33 -0000 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;