Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Jan 2015 20:00:56 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r277813 - in user/cperciva/freebsd-update-build/patches: 10.0-RELEASE 10.1-RELEASE 8.4-RELEASE 9.3-RELEASE
Message-ID:  <201501272000.t0RK0uRF028516@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Tue Jan 27 20:00:55 2015
New Revision: 277813
URL: https://svnweb.freebsd.org/changeset/base/277813

Log:
  Add patches for 2015-01-27 batch.

Added:
  user/cperciva/freebsd-update-build/patches/10.0-RELEASE/17-SA-15:02.kmem
  user/cperciva/freebsd-update-build/patches/10.0-RELEASE/17-SA-15:03.sctp
  user/cperciva/freebsd-update-build/patches/10.1-RELEASE/5-SA-15:02.kmem
  user/cperciva/freebsd-update-build/patches/10.1-RELEASE/5-SA-15:03.sctp
  user/cperciva/freebsd-update-build/patches/8.4-RELEASE/23-SA-15:02.kmem
  user/cperciva/freebsd-update-build/patches/8.4-RELEASE/23-SA-15:03.sctp
  user/cperciva/freebsd-update-build/patches/9.3-RELEASE/9-SA-15:02.kmem
  user/cperciva/freebsd-update-build/patches/9.3-RELEASE/9-SA-15:03.sctp

Added: user/cperciva/freebsd-update-build/patches/10.0-RELEASE/17-SA-15:02.kmem
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/10.0-RELEASE/17-SA-15:02.kmem	Tue Jan 27 20:00:55 2015	(r277813)
@@ -0,0 +1,45 @@
+Index: sys/netinet/sctp_usrreq.c
+===================================================================
+--- sys/netinet/sctp_usrreq.c	(revision 277788)
++++ sys/netinet/sctp_usrreq.c	(working copy)
+@@ -1863,8 +1863,9 @@ flags_out:
+ 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, *optsize);
+ 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
+ 			if (stcb) {
+-				if (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
+-				    &av->stream_value) < 0) {
++				if ((av->stream_id >= stcb->asoc.streamoutcnt) ||
++				    (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
++				    &av->stream_value) < 0)) {
+ 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ 					error = EINVAL;
+ 				} else {
+@@ -4032,8 +4033,9 @@ sctp_setopt(struct socket *so, int optname, void *
+ 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, optsize);
+ 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
+ 			if (stcb) {
+-				if (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
+-				    av->stream_value) < 0) {
++				if ((av->stream_id >= stcb->asoc.streamoutcnt) ||
++				    (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
++				    av->stream_value) < 0)) {
+ 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ 					error = EINVAL;
+ 				}
+@@ -4043,10 +4045,12 @@ sctp_setopt(struct socket *so, int optname, void *
+ 					SCTP_INP_RLOCK(inp);
+ 					LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
+ 						SCTP_TCB_LOCK(stcb);
+-						stcb->asoc.ss_functions.sctp_ss_set_value(stcb,
+-						    &stcb->asoc,
+-						    &stcb->asoc.strmout[av->stream_id],
+-						    av->stream_value);
++						if (av->stream_id < stcb->asoc.streamoutcnt) {
++							stcb->asoc.ss_functions.sctp_ss_set_value(stcb,
++							    &stcb->asoc,
++							    &stcb->asoc.strmout[av->stream_id],
++							    av->stream_value);
++						}
+ 						SCTP_TCB_UNLOCK(stcb);
+ 					}
+ 					SCTP_INP_RUNLOCK(inp);

Added: user/cperciva/freebsd-update-build/patches/10.0-RELEASE/17-SA-15:03.sctp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/10.0-RELEASE/17-SA-15:03.sctp	Tue Jan 27 20:00:55 2015	(r277813)
@@ -0,0 +1,119 @@
+Index: sys/netinet/sctp_input.c
+===================================================================
+--- sys/netinet/sctp_input.c	(revision 277788)
++++ sys/netinet/sctp_input.c	(working copy)
+@@ -3649,6 +3649,9 @@ sctp_handle_stream_reset_response(struct sctp_tcb
+ 					/* huh ? */
+ 					return (0);
+ 				}
++				if (ntohs(respin->ph.param_length) < sizeof(struct sctp_stream_reset_response_tsn)) {
++					return (0);
++				}
+ 				if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) {
+ 					resp = (struct sctp_stream_reset_response_tsn *)respin;
+ 					asoc->stream_reset_outstanding--;
+@@ -4037,7 +4040,7 @@ __attribute__((noinline))
+ 	    sctp_handle_stream_reset(struct sctp_tcb *stcb, struct mbuf *m, int offset,
+         struct sctp_chunkhdr *ch_req)
+ {
+-	int chk_length, param_len, ptype;
++	uint16_t remaining_length, param_len, ptype;
+ 	struct sctp_paramhdr pstore;
+ 	uint8_t cstore[SCTP_CHUNK_BUFFER_SIZE];
+ 	uint32_t seq = 0;
+@@ -4050,7 +4053,7 @@ __attribute__((noinline))
+ 	int num_param = 0;
+ 
+ 	/* now it may be a reset or a reset-response */
+-	chk_length = ntohs(ch_req->chunk_length);
++	remaining_length = ntohs(ch_req->chunk_length) - sizeof(struct sctp_chunkhdr);
+ 
+ 	/* setup for adding the response */
+ 	sctp_alloc_a_chunk(stcb, chk);
+@@ -4088,20 +4091,27 @@ strres_nochunk:
+ 	ch->chunk_length = htons(chk->send_size);
+ 	SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size);
+ 	offset += sizeof(struct sctp_chunkhdr);
+-	while ((size_t)chk_length >= sizeof(struct sctp_stream_reset_tsn_request)) {
++	while (remaining_length >= sizeof(struct sctp_paramhdr)) {
+ 		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, sizeof(pstore), (uint8_t *) & pstore);
+-		if (ph == NULL)
++		if (ph == NULL) {
++			/* TSNH */
+ 			break;
++		}
+ 		param_len = ntohs(ph->param_length);
+-		if (param_len < (int)sizeof(struct sctp_stream_reset_tsn_request)) {
+-			/* bad param */
++		if ((param_len > remaining_length) ||
++		    (param_len < (sizeof(struct sctp_paramhdr) + sizeof(uint32_t)))) {
++			/* bad parameter length */
+ 			break;
+ 		}
+-		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, min(param_len, (int)sizeof(cstore)),
++		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, min(param_len, sizeof(cstore)),
+ 		    (uint8_t *) & cstore);
++		if (ph == NULL) {
++			/* TSNH */
++			break;
++		}
+ 		ptype = ntohs(ph->param_type);
+ 		num_param++;
+-		if (param_len > (int)sizeof(cstore)) {
++		if (param_len > sizeof(cstore)) {
+ 			trunc = 1;
+ 		} else {
+ 			trunc = 0;
+@@ -4113,6 +4123,9 @@ strres_nochunk:
+ 		if (ptype == SCTP_STR_RESET_OUT_REQUEST) {
+ 			struct sctp_stream_reset_out_request *req_out;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_out_request)) {
++				break;
++			}
+ 			req_out = (struct sctp_stream_reset_out_request *)ph;
+ 			num_req++;
+ 			if (stcb->asoc.stream_reset_outstanding) {
+@@ -4126,6 +4139,9 @@ strres_nochunk:
+ 		} else if (ptype == SCTP_STR_RESET_ADD_OUT_STREAMS) {
+ 			struct sctp_stream_reset_add_strm *str_add;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_add_strm)) {
++				break;
++			}
+ 			str_add = (struct sctp_stream_reset_add_strm *)ph;
+ 			num_req++;
+ 			sctp_handle_str_reset_add_strm(stcb, chk, str_add);
+@@ -4132,6 +4148,9 @@ strres_nochunk:
+ 		} else if (ptype == SCTP_STR_RESET_ADD_IN_STREAMS) {
+ 			struct sctp_stream_reset_add_strm *str_add;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_add_strm)) {
++				break;
++			}
+ 			str_add = (struct sctp_stream_reset_add_strm *)ph;
+ 			num_req++;
+ 			sctp_handle_str_reset_add_out_strm(stcb, chk, str_add);
+@@ -4156,6 +4175,9 @@ strres_nochunk:
+ 			struct sctp_stream_reset_response *resp;
+ 			uint32_t result;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_response)) {
++				break;
++			}
+ 			resp = (struct sctp_stream_reset_response *)ph;
+ 			seq = ntohl(resp->response_seq);
+ 			result = ntohl(resp->result);
+@@ -4167,7 +4189,11 @@ strres_nochunk:
+ 			break;
+ 		}
+ 		offset += SCTP_SIZE32(param_len);
+-		chk_length -= SCTP_SIZE32(param_len);
++		if (remaining_length >= SCTP_SIZE32(param_len)) {
++			remaining_length -= SCTP_SIZE32(param_len);
++		} else {
++			remaining_length = 0;
++		}
+ 	}
+ 	if (num_req == 0) {
+ 		/* we have no response free the stuff */

Added: user/cperciva/freebsd-update-build/patches/10.1-RELEASE/5-SA-15:02.kmem
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/10.1-RELEASE/5-SA-15:02.kmem	Tue Jan 27 20:00:55 2015	(r277813)
@@ -0,0 +1,45 @@
+Index: sys/netinet/sctp_usrreq.c
+===================================================================
+--- sys/netinet/sctp_usrreq.c	(revision 277788)
++++ sys/netinet/sctp_usrreq.c	(working copy)
+@@ -1863,8 +1863,9 @@ flags_out:
+ 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, *optsize);
+ 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
+ 			if (stcb) {
+-				if (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
+-				    &av->stream_value) < 0) {
++				if ((av->stream_id >= stcb->asoc.streamoutcnt) ||
++				    (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
++				    &av->stream_value) < 0)) {
+ 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ 					error = EINVAL;
+ 				} else {
+@@ -4032,8 +4033,9 @@ sctp_setopt(struct socket *so, int optname, void *
+ 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, optsize);
+ 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
+ 			if (stcb) {
+-				if (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
+-				    av->stream_value) < 0) {
++				if ((av->stream_id >= stcb->asoc.streamoutcnt) ||
++				    (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
++				    av->stream_value) < 0)) {
+ 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ 					error = EINVAL;
+ 				}
+@@ -4043,10 +4045,12 @@ sctp_setopt(struct socket *so, int optname, void *
+ 					SCTP_INP_RLOCK(inp);
+ 					LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
+ 						SCTP_TCB_LOCK(stcb);
+-						stcb->asoc.ss_functions.sctp_ss_set_value(stcb,
+-						    &stcb->asoc,
+-						    &stcb->asoc.strmout[av->stream_id],
+-						    av->stream_value);
++						if (av->stream_id < stcb->asoc.streamoutcnt) {
++							stcb->asoc.ss_functions.sctp_ss_set_value(stcb,
++							    &stcb->asoc,
++							    &stcb->asoc.strmout[av->stream_id],
++							    av->stream_value);
++						}
+ 						SCTP_TCB_UNLOCK(stcb);
+ 					}
+ 					SCTP_INP_RUNLOCK(inp);

Added: user/cperciva/freebsd-update-build/patches/10.1-RELEASE/5-SA-15:03.sctp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/10.1-RELEASE/5-SA-15:03.sctp	Tue Jan 27 20:00:55 2015	(r277813)
@@ -0,0 +1,119 @@
+Index: sys/netinet/sctp_input.c
+===================================================================
+--- sys/netinet/sctp_input.c	(revision 277788)
++++ sys/netinet/sctp_input.c	(working copy)
+@@ -3649,6 +3649,9 @@ sctp_handle_stream_reset_response(struct sctp_tcb
+ 					/* huh ? */
+ 					return (0);
+ 				}
++				if (ntohs(respin->ph.param_length) < sizeof(struct sctp_stream_reset_response_tsn)) {
++					return (0);
++				}
+ 				if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) {
+ 					resp = (struct sctp_stream_reset_response_tsn *)respin;
+ 					asoc->stream_reset_outstanding--;
+@@ -4037,7 +4040,7 @@ __attribute__((noinline))
+ 	    sctp_handle_stream_reset(struct sctp_tcb *stcb, struct mbuf *m, int offset,
+         struct sctp_chunkhdr *ch_req)
+ {
+-	int chk_length, param_len, ptype;
++	uint16_t remaining_length, param_len, ptype;
+ 	struct sctp_paramhdr pstore;
+ 	uint8_t cstore[SCTP_CHUNK_BUFFER_SIZE];
+ 	uint32_t seq = 0;
+@@ -4050,7 +4053,7 @@ __attribute__((noinline))
+ 	int num_param = 0;
+ 
+ 	/* now it may be a reset or a reset-response */
+-	chk_length = ntohs(ch_req->chunk_length);
++	remaining_length = ntohs(ch_req->chunk_length) - sizeof(struct sctp_chunkhdr);
+ 
+ 	/* setup for adding the response */
+ 	sctp_alloc_a_chunk(stcb, chk);
+@@ -4088,20 +4091,27 @@ strres_nochunk:
+ 	ch->chunk_length = htons(chk->send_size);
+ 	SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size);
+ 	offset += sizeof(struct sctp_chunkhdr);
+-	while ((size_t)chk_length >= sizeof(struct sctp_stream_reset_tsn_request)) {
++	while (remaining_length >= sizeof(struct sctp_paramhdr)) {
+ 		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, sizeof(pstore), (uint8_t *) & pstore);
+-		if (ph == NULL)
++		if (ph == NULL) {
++			/* TSNH */
+ 			break;
++		}
+ 		param_len = ntohs(ph->param_length);
+-		if (param_len < (int)sizeof(struct sctp_stream_reset_tsn_request)) {
+-			/* bad param */
++		if ((param_len > remaining_length) ||
++		    (param_len < (sizeof(struct sctp_paramhdr) + sizeof(uint32_t)))) {
++			/* bad parameter length */
+ 			break;
+ 		}
+-		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, min(param_len, (int)sizeof(cstore)),
++		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, min(param_len, sizeof(cstore)),
+ 		    (uint8_t *) & cstore);
++		if (ph == NULL) {
++			/* TSNH */
++			break;
++		}
+ 		ptype = ntohs(ph->param_type);
+ 		num_param++;
+-		if (param_len > (int)sizeof(cstore)) {
++		if (param_len > sizeof(cstore)) {
+ 			trunc = 1;
+ 		} else {
+ 			trunc = 0;
+@@ -4113,6 +4123,9 @@ strres_nochunk:
+ 		if (ptype == SCTP_STR_RESET_OUT_REQUEST) {
+ 			struct sctp_stream_reset_out_request *req_out;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_out_request)) {
++				break;
++			}
+ 			req_out = (struct sctp_stream_reset_out_request *)ph;
+ 			num_req++;
+ 			if (stcb->asoc.stream_reset_outstanding) {
+@@ -4126,6 +4139,9 @@ strres_nochunk:
+ 		} else if (ptype == SCTP_STR_RESET_ADD_OUT_STREAMS) {
+ 			struct sctp_stream_reset_add_strm *str_add;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_add_strm)) {
++				break;
++			}
+ 			str_add = (struct sctp_stream_reset_add_strm *)ph;
+ 			num_req++;
+ 			sctp_handle_str_reset_add_strm(stcb, chk, str_add);
+@@ -4132,6 +4148,9 @@ strres_nochunk:
+ 		} else if (ptype == SCTP_STR_RESET_ADD_IN_STREAMS) {
+ 			struct sctp_stream_reset_add_strm *str_add;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_add_strm)) {
++				break;
++			}
+ 			str_add = (struct sctp_stream_reset_add_strm *)ph;
+ 			num_req++;
+ 			sctp_handle_str_reset_add_out_strm(stcb, chk, str_add);
+@@ -4156,6 +4175,9 @@ strres_nochunk:
+ 			struct sctp_stream_reset_response *resp;
+ 			uint32_t result;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_response)) {
++				break;
++			}
+ 			resp = (struct sctp_stream_reset_response *)ph;
+ 			seq = ntohl(resp->response_seq);
+ 			result = ntohl(resp->result);
+@@ -4167,7 +4189,11 @@ strres_nochunk:
+ 			break;
+ 		}
+ 		offset += SCTP_SIZE32(param_len);
+-		chk_length -= SCTP_SIZE32(param_len);
++		if (remaining_length >= SCTP_SIZE32(param_len)) {
++			remaining_length -= SCTP_SIZE32(param_len);
++		} else {
++			remaining_length = 0;
++		}
+ 	}
+ 	if (num_req == 0) {
+ 		/* we have no response free the stuff */

Added: user/cperciva/freebsd-update-build/patches/8.4-RELEASE/23-SA-15:02.kmem
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/8.4-RELEASE/23-SA-15:02.kmem	Tue Jan 27 20:00:55 2015	(r277813)
@@ -0,0 +1,45 @@
+Index: sys/netinet/sctp_usrreq.c
+===================================================================
+--- sys/netinet/sctp_usrreq.c	(revision 277788)
++++ sys/netinet/sctp_usrreq.c	(working copy)
+@@ -1863,8 +1863,9 @@ flags_out:
+ 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, *optsize);
+ 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
+ 			if (stcb) {
+-				if (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
+-				    &av->stream_value) < 0) {
++				if ((av->stream_id >= stcb->asoc.streamoutcnt) ||
++				    (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
++				    &av->stream_value) < 0)) {
+ 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ 					error = EINVAL;
+ 				} else {
+@@ -4032,8 +4033,9 @@ sctp_setopt(struct socket *so, int optname, void *
+ 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, optsize);
+ 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
+ 			if (stcb) {
+-				if (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
+-				    av->stream_value) < 0) {
++				if ((av->stream_id >= stcb->asoc.streamoutcnt) ||
++				    (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
++				    av->stream_value) < 0)) {
+ 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ 					error = EINVAL;
+ 				}
+@@ -4043,10 +4045,12 @@ sctp_setopt(struct socket *so, int optname, void *
+ 					SCTP_INP_RLOCK(inp);
+ 					LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
+ 						SCTP_TCB_LOCK(stcb);
+-						stcb->asoc.ss_functions.sctp_ss_set_value(stcb,
+-						    &stcb->asoc,
+-						    &stcb->asoc.strmout[av->stream_id],
+-						    av->stream_value);
++						if (av->stream_id < stcb->asoc.streamoutcnt) {
++							stcb->asoc.ss_functions.sctp_ss_set_value(stcb,
++							    &stcb->asoc,
++							    &stcb->asoc.strmout[av->stream_id],
++							    av->stream_value);
++						}
+ 						SCTP_TCB_UNLOCK(stcb);
+ 					}
+ 					SCTP_INP_RUNLOCK(inp);

Added: user/cperciva/freebsd-update-build/patches/8.4-RELEASE/23-SA-15:03.sctp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/8.4-RELEASE/23-SA-15:03.sctp	Tue Jan 27 20:00:55 2015	(r277813)
@@ -0,0 +1,119 @@
+Index: sys/netinet/sctp_input.c
+===================================================================
+--- sys/netinet/sctp_input.c	(revision 277788)
++++ sys/netinet/sctp_input.c	(working copy)
+@@ -3649,6 +3649,9 @@ sctp_handle_stream_reset_response(struct sctp_tcb
+ 					/* huh ? */
+ 					return (0);
+ 				}
++				if (ntohs(respin->ph.param_length) < sizeof(struct sctp_stream_reset_response_tsn)) {
++					return (0);
++				}
+ 				if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) {
+ 					resp = (struct sctp_stream_reset_response_tsn *)respin;
+ 					asoc->stream_reset_outstanding--;
+@@ -4037,7 +4040,7 @@ __attribute__((noinline))
+ 	    sctp_handle_stream_reset(struct sctp_tcb *stcb, struct mbuf *m, int offset,
+         struct sctp_chunkhdr *ch_req)
+ {
+-	int chk_length, param_len, ptype;
++	uint16_t remaining_length, param_len, ptype;
+ 	struct sctp_paramhdr pstore;
+ 	uint8_t cstore[SCTP_CHUNK_BUFFER_SIZE];
+ 	uint32_t seq = 0;
+@@ -4050,7 +4053,7 @@ __attribute__((noinline))
+ 	int num_param = 0;
+ 
+ 	/* now it may be a reset or a reset-response */
+-	chk_length = ntohs(ch_req->chunk_length);
++	remaining_length = ntohs(ch_req->chunk_length) - sizeof(struct sctp_chunkhdr);
+ 
+ 	/* setup for adding the response */
+ 	sctp_alloc_a_chunk(stcb, chk);
+@@ -4088,20 +4091,27 @@ strres_nochunk:
+ 	ch->chunk_length = htons(chk->send_size);
+ 	SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size);
+ 	offset += sizeof(struct sctp_chunkhdr);
+-	while ((size_t)chk_length >= sizeof(struct sctp_stream_reset_tsn_request)) {
++	while (remaining_length >= sizeof(struct sctp_paramhdr)) {
+ 		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, sizeof(pstore), (uint8_t *) & pstore);
+-		if (ph == NULL)
++		if (ph == NULL) {
++			/* TSNH */
+ 			break;
++		}
+ 		param_len = ntohs(ph->param_length);
+-		if (param_len < (int)sizeof(struct sctp_stream_reset_tsn_request)) {
+-			/* bad param */
++		if ((param_len > remaining_length) ||
++		    (param_len < (sizeof(struct sctp_paramhdr) + sizeof(uint32_t)))) {
++			/* bad parameter length */
+ 			break;
+ 		}
+-		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, min(param_len, (int)sizeof(cstore)),
++		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, min(param_len, sizeof(cstore)),
+ 		    (uint8_t *) & cstore);
++		if (ph == NULL) {
++			/* TSNH */
++			break;
++		}
+ 		ptype = ntohs(ph->param_type);
+ 		num_param++;
+-		if (param_len > (int)sizeof(cstore)) {
++		if (param_len > sizeof(cstore)) {
+ 			trunc = 1;
+ 		} else {
+ 			trunc = 0;
+@@ -4113,6 +4123,9 @@ strres_nochunk:
+ 		if (ptype == SCTP_STR_RESET_OUT_REQUEST) {
+ 			struct sctp_stream_reset_out_request *req_out;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_out_request)) {
++				break;
++			}
+ 			req_out = (struct sctp_stream_reset_out_request *)ph;
+ 			num_req++;
+ 			if (stcb->asoc.stream_reset_outstanding) {
+@@ -4126,6 +4139,9 @@ strres_nochunk:
+ 		} else if (ptype == SCTP_STR_RESET_ADD_OUT_STREAMS) {
+ 			struct sctp_stream_reset_add_strm *str_add;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_add_strm)) {
++				break;
++			}
+ 			str_add = (struct sctp_stream_reset_add_strm *)ph;
+ 			num_req++;
+ 			sctp_handle_str_reset_add_strm(stcb, chk, str_add);
+@@ -4132,6 +4148,9 @@ strres_nochunk:
+ 		} else if (ptype == SCTP_STR_RESET_ADD_IN_STREAMS) {
+ 			struct sctp_stream_reset_add_strm *str_add;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_add_strm)) {
++				break;
++			}
+ 			str_add = (struct sctp_stream_reset_add_strm *)ph;
+ 			num_req++;
+ 			sctp_handle_str_reset_add_out_strm(stcb, chk, str_add);
+@@ -4156,6 +4175,9 @@ strres_nochunk:
+ 			struct sctp_stream_reset_response *resp;
+ 			uint32_t result;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_response)) {
++				break;
++			}
+ 			resp = (struct sctp_stream_reset_response *)ph;
+ 			seq = ntohl(resp->response_seq);
+ 			result = ntohl(resp->result);
+@@ -4167,7 +4189,11 @@ strres_nochunk:
+ 			break;
+ 		}
+ 		offset += SCTP_SIZE32(param_len);
+-		chk_length -= SCTP_SIZE32(param_len);
++		if (remaining_length >= SCTP_SIZE32(param_len)) {
++			remaining_length -= SCTP_SIZE32(param_len);
++		} else {
++			remaining_length = 0;
++		}
+ 	}
+ 	if (num_req == 0) {
+ 		/* we have no response free the stuff */

Added: user/cperciva/freebsd-update-build/patches/9.3-RELEASE/9-SA-15:02.kmem
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/9.3-RELEASE/9-SA-15:02.kmem	Tue Jan 27 20:00:55 2015	(r277813)
@@ -0,0 +1,45 @@
+Index: sys/netinet/sctp_usrreq.c
+===================================================================
+--- sys/netinet/sctp_usrreq.c	(revision 277788)
++++ sys/netinet/sctp_usrreq.c	(working copy)
+@@ -1863,8 +1863,9 @@ flags_out:
+ 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, *optsize);
+ 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
+ 			if (stcb) {
+-				if (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
+-				    &av->stream_value) < 0) {
++				if ((av->stream_id >= stcb->asoc.streamoutcnt) ||
++				    (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
++				    &av->stream_value) < 0)) {
+ 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ 					error = EINVAL;
+ 				} else {
+@@ -4032,8 +4033,9 @@ sctp_setopt(struct socket *so, int optname, void *
+ 			SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, optsize);
+ 			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
+ 			if (stcb) {
+-				if (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
+-				    av->stream_value) < 0) {
++				if ((av->stream_id >= stcb->asoc.streamoutcnt) ||
++				    (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
++				    av->stream_value) < 0)) {
+ 					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ 					error = EINVAL;
+ 				}
+@@ -4043,10 +4045,12 @@ sctp_setopt(struct socket *so, int optname, void *
+ 					SCTP_INP_RLOCK(inp);
+ 					LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
+ 						SCTP_TCB_LOCK(stcb);
+-						stcb->asoc.ss_functions.sctp_ss_set_value(stcb,
+-						    &stcb->asoc,
+-						    &stcb->asoc.strmout[av->stream_id],
+-						    av->stream_value);
++						if (av->stream_id < stcb->asoc.streamoutcnt) {
++							stcb->asoc.ss_functions.sctp_ss_set_value(stcb,
++							    &stcb->asoc,
++							    &stcb->asoc.strmout[av->stream_id],
++							    av->stream_value);
++						}
+ 						SCTP_TCB_UNLOCK(stcb);
+ 					}
+ 					SCTP_INP_RUNLOCK(inp);

Added: user/cperciva/freebsd-update-build/patches/9.3-RELEASE/9-SA-15:03.sctp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/cperciva/freebsd-update-build/patches/9.3-RELEASE/9-SA-15:03.sctp	Tue Jan 27 20:00:55 2015	(r277813)
@@ -0,0 +1,119 @@
+Index: sys/netinet/sctp_input.c
+===================================================================
+--- sys/netinet/sctp_input.c	(revision 277788)
++++ sys/netinet/sctp_input.c	(working copy)
+@@ -3649,6 +3649,9 @@ sctp_handle_stream_reset_response(struct sctp_tcb
+ 					/* huh ? */
+ 					return (0);
+ 				}
++				if (ntohs(respin->ph.param_length) < sizeof(struct sctp_stream_reset_response_tsn)) {
++					return (0);
++				}
+ 				if (action == SCTP_STREAM_RESET_RESULT_PERFORMED) {
+ 					resp = (struct sctp_stream_reset_response_tsn *)respin;
+ 					asoc->stream_reset_outstanding--;
+@@ -4037,7 +4040,7 @@ __attribute__((noinline))
+ 	    sctp_handle_stream_reset(struct sctp_tcb *stcb, struct mbuf *m, int offset,
+         struct sctp_chunkhdr *ch_req)
+ {
+-	int chk_length, param_len, ptype;
++	uint16_t remaining_length, param_len, ptype;
+ 	struct sctp_paramhdr pstore;
+ 	uint8_t cstore[SCTP_CHUNK_BUFFER_SIZE];
+ 	uint32_t seq = 0;
+@@ -4050,7 +4053,7 @@ __attribute__((noinline))
+ 	int num_param = 0;
+ 
+ 	/* now it may be a reset or a reset-response */
+-	chk_length = ntohs(ch_req->chunk_length);
++	remaining_length = ntohs(ch_req->chunk_length) - sizeof(struct sctp_chunkhdr);
+ 
+ 	/* setup for adding the response */
+ 	sctp_alloc_a_chunk(stcb, chk);
+@@ -4088,20 +4091,27 @@ strres_nochunk:
+ 	ch->chunk_length = htons(chk->send_size);
+ 	SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size);
+ 	offset += sizeof(struct sctp_chunkhdr);
+-	while ((size_t)chk_length >= sizeof(struct sctp_stream_reset_tsn_request)) {
++	while (remaining_length >= sizeof(struct sctp_paramhdr)) {
+ 		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, sizeof(pstore), (uint8_t *) & pstore);
+-		if (ph == NULL)
++		if (ph == NULL) {
++			/* TSNH */
+ 			break;
++		}
+ 		param_len = ntohs(ph->param_length);
+-		if (param_len < (int)sizeof(struct sctp_stream_reset_tsn_request)) {
+-			/* bad param */
++		if ((param_len > remaining_length) ||
++		    (param_len < (sizeof(struct sctp_paramhdr) + sizeof(uint32_t)))) {
++			/* bad parameter length */
+ 			break;
+ 		}
+-		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, min(param_len, (int)sizeof(cstore)),
++		ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, min(param_len, sizeof(cstore)),
+ 		    (uint8_t *) & cstore);
++		if (ph == NULL) {
++			/* TSNH */
++			break;
++		}
+ 		ptype = ntohs(ph->param_type);
+ 		num_param++;
+-		if (param_len > (int)sizeof(cstore)) {
++		if (param_len > sizeof(cstore)) {
+ 			trunc = 1;
+ 		} else {
+ 			trunc = 0;
+@@ -4113,6 +4123,9 @@ strres_nochunk:
+ 		if (ptype == SCTP_STR_RESET_OUT_REQUEST) {
+ 			struct sctp_stream_reset_out_request *req_out;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_out_request)) {
++				break;
++			}
+ 			req_out = (struct sctp_stream_reset_out_request *)ph;
+ 			num_req++;
+ 			if (stcb->asoc.stream_reset_outstanding) {
+@@ -4126,6 +4139,9 @@ strres_nochunk:
+ 		} else if (ptype == SCTP_STR_RESET_ADD_OUT_STREAMS) {
+ 			struct sctp_stream_reset_add_strm *str_add;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_add_strm)) {
++				break;
++			}
+ 			str_add = (struct sctp_stream_reset_add_strm *)ph;
+ 			num_req++;
+ 			sctp_handle_str_reset_add_strm(stcb, chk, str_add);
+@@ -4132,6 +4148,9 @@ strres_nochunk:
+ 		} else if (ptype == SCTP_STR_RESET_ADD_IN_STREAMS) {
+ 			struct sctp_stream_reset_add_strm *str_add;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_add_strm)) {
++				break;
++			}
+ 			str_add = (struct sctp_stream_reset_add_strm *)ph;
+ 			num_req++;
+ 			sctp_handle_str_reset_add_out_strm(stcb, chk, str_add);
+@@ -4156,6 +4175,9 @@ strres_nochunk:
+ 			struct sctp_stream_reset_response *resp;
+ 			uint32_t result;
+ 
++			if (param_len < sizeof(struct sctp_stream_reset_response)) {
++				break;
++			}
+ 			resp = (struct sctp_stream_reset_response *)ph;
+ 			seq = ntohl(resp->response_seq);
+ 			result = ntohl(resp->result);
+@@ -4167,7 +4189,11 @@ strres_nochunk:
+ 			break;
+ 		}
+ 		offset += SCTP_SIZE32(param_len);
+-		chk_length -= SCTP_SIZE32(param_len);
++		if (remaining_length >= SCTP_SIZE32(param_len)) {
++			remaining_length -= SCTP_SIZE32(param_len);
++		} else {
++			remaining_length = 0;
++		}
+ 	}
+ 	if (num_req == 0) {
+ 		/* we have no response free the stuff */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501272000.t0RK0uRF028516>