summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'sys-freebsd/freebsd-sources/files/freebsd-sources-10.1-cve-2014-8613.patch')
-rw-r--r--sys-freebsd/freebsd-sources/files/freebsd-sources-10.1-cve-2014-8613.patch119
1 files changed, 119 insertions, 0 deletions
diff --git a/sys-freebsd/freebsd-sources/files/freebsd-sources-10.1-cve-2014-8613.patch b/sys-freebsd/freebsd-sources/files/freebsd-sources-10.1-cve-2014-8613.patch
new file mode 100644
index 000000000000..1e2fe912335c
--- /dev/null
+++ b/sys-freebsd/freebsd-sources/files/freebsd-sources-10.1-cve-2014-8613.patch
@@ -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 */