Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 May 2020 15:48:27 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org
Subject:   svn commit: r361522 - releng/11.4/sys/netinet
Message-ID:  <202005261548.04QFmRR0070614@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Tue May 26 15:48:27 2020
New Revision: 361522
URL: https://svnweb.freebsd.org/changeset/base/361522

Log:
  MFS r361469: Fix bug in PR-SCTP
  Only drop DATA chunk with lower priorities as specified in RFC 7496.
  This issue was found by looking at a reproducer generated by syzkaller.
  
  MFS r361472: Improve SCTP iterator
  Ensure that the SCTP iterator runs with an stcb and inp, which belong to
  each other.
  
  MFS r361473: Improve stcb handling during teardown
  Ensure that an stcb is not dereferenced when it is about to be freed.
  This issue was found by SYZKALLER.
  
  MFS r361476: Improve ASCONF handling
  Avoid an integer underflow.
  
  Approved by:	re(gjb)

Modified:
  releng/11.4/sys/netinet/sctp_asconf.c
  releng/11.4/sys/netinet/sctp_indata.c
  releng/11.4/sys/netinet/sctp_indata.h
  releng/11.4/sys/netinet/sctp_output.c
  releng/11.4/sys/netinet/sctputil.c
Directory Properties:
  releng/11.4/   (props changed)

Modified: releng/11.4/sys/netinet/sctp_asconf.c
==============================================================================
--- releng/11.4/sys/netinet/sctp_asconf.c	Tue May 26 15:48:06 2020	(r361521)
+++ releng/11.4/sys/netinet/sctp_asconf.c	Tue May 26 15:48:27 2020	(r361522)
@@ -1797,9 +1797,9 @@ sctp_handle_asconf_ack(struct mbuf *m, int offset,
 		}		/* switch */
 
 		/* update remaining ASCONF-ACK message length to process */
-		ack_length -= SCTP_SIZE32(param_length);
-		if (ack_length <= 0) {
-			/* no more data in the mbuf chain */
+		if (ack_length > SCTP_SIZE32(param_length)) {
+			ack_length -= SCTP_SIZE32(param_length);
+		} else {
 			break;
 		}
 		offset += SCTP_SIZE32(param_length);

Modified: releng/11.4/sys/netinet/sctp_indata.c
==============================================================================
--- releng/11.4/sys/netinet/sctp_indata.c	Tue May 26 15:48:06 2020	(r361521)
+++ releng/11.4/sys/netinet/sctp_indata.c	Tue May 26 15:48:27 2020	(r361522)
@@ -162,6 +162,9 @@ sctp_build_readq_entry(struct sctp_tcb *stcb,
 	read_queue_e->data = dm;
 	read_queue_e->stcb = stcb;
 	read_queue_e->port_from = stcb->rport;
+	if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+		read_queue_e->do_not_ref_stcb = 1;
+	}
 failed_build:
 	return (read_queue_e);
 }
@@ -773,6 +776,7 @@ sctp_build_readq_entry_from_ctl(struct sctp_queued_to_
 	atomic_add_int(&nc->whoFrom->ref_count, 1);
 	nc->stcb = control->stcb;
 	nc->port_from = control->port_from;
+	nc->do_not_ref_stcb = control->do_not_ref_stcb;
 }
 
 static void

Modified: releng/11.4/sys/netinet/sctp_indata.h
==============================================================================
--- releng/11.4/sys/netinet/sctp_indata.h	Tue May 26 15:48:06 2020	(r361521)
+++ releng/11.4/sys/netinet/sctp_indata.h	Tue May 26 15:48:27 2020	(r361522)
@@ -66,6 +66,9 @@ sctp_build_readq_entry(struct sctp_tcb *stcb,
 		(_ctl)->data = dm; \
 		(_ctl)->stcb = (in_it); \
 		(_ctl)->port_from = (in_it)->rport; \
+		if ((in_it)->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { \
+			(_ctl)->do_not_ref_stcb = 1; \
+		}\
 	} \
 } while (0)
 

Modified: releng/11.4/sys/netinet/sctp_output.c
==============================================================================
--- releng/11.4/sys/netinet/sctp_output.c	Tue May 26 15:48:06 2020	(r361521)
+++ releng/11.4/sys/netinet/sctp_output.c	Tue May 26 15:48:27 2020	(r361522)
@@ -6198,11 +6198,11 @@ sctp_prune_prsctp(struct sctp_tcb *stcb,
 				 * This one is PR-SCTP AND buffer space
 				 * limited type
 				 */
-				if (chk->rec.data.timetodrop.tv_sec >= (long)srcv->sinfo_timetolive) {
+				if (chk->rec.data.timetodrop.tv_sec > (long)srcv->sinfo_timetolive) {
 					/*
 					 * Lower numbers equates to higher
 					 * priority so if the one we are
-					 * looking at has a larger or equal
+					 * looking at has a larger
 					 * priority we want to drop the data
 					 * and NOT retransmit it.
 					 */
@@ -6233,7 +6233,7 @@ sctp_prune_prsctp(struct sctp_tcb *stcb,
 		TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
 			/* Here we must move to the sent queue and mark */
 			if (PR_SCTP_BUF_ENABLED(chk->flags)) {
-				if (chk->rec.data.timetodrop.tv_sec >= (long)srcv->sinfo_timetolive) {
+				if (chk->rec.data.timetodrop.tv_sec > (long)srcv->sinfo_timetolive) {
 					if (chk->data) {
 						/*
 						 * We release the book_size
@@ -12614,7 +12614,7 @@ sctp_lower_sosend(struct socket *so,
 		top = SCTP_HEADER_TO_CHAIN(i_pak);
 		sndlen = SCTP_HEADER_LEN(i_pak);
 	}
-	SCTPDBG(SCTP_DEBUG_OUTPUT1, "Send called addr:%p send length %zu\n",
+	SCTPDBG(SCTP_DEBUG_OUTPUT1, "Send called addr:%p send length %zd\n",
 	    (void *)addr,
 	    sndlen);
 	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&

Modified: releng/11.4/sys/netinet/sctputil.c
==============================================================================
--- releng/11.4/sys/netinet/sctputil.c	Tue May 26 15:48:06 2020	(r361521)
+++ releng/11.4/sys/netinet/sctputil.c	Tue May 26 15:48:27 2020	(r361522)
@@ -1409,6 +1409,7 @@ select_a_new_ep:
 		}
 		tinp = it->inp;
 		it->inp = LIST_NEXT(it->inp, sctp_list);
+		it->stcb = NULL;
 		SCTP_INP_RUNLOCK(tinp);
 		if (it->inp == NULL) {
 			goto done_with_iterator;
@@ -1478,6 +1479,9 @@ select_a_new_ep:
 			atomic_add_int(&it->stcb->asoc.refcnt, -1);
 			iteration_count = 0;
 		}
+		KASSERT(it->inp == it->stcb->sctp_ep,
+		        ("%s: stcb %p does not belong to inp %p, but inp %p",
+		         __func__, it->stcb, it->inp, it->stcb->sctp_ep));
 
 		/* run function on this one */
 		(*it->function_assoc) (it->inp, it->stcb, it->pointer, it->val);
@@ -1510,6 +1514,7 @@ no_stcb:
 	} else {
 		it->inp = LIST_NEXT(it->inp, sctp_list);
 	}
+	it->stcb = NULL;
 	if (it->inp == NULL) {
 		goto done_with_iterator;
 	}



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