svn commit: r344723 - head/sys/netinet

Michael Tuexen tuexen at FreeBSD.org
Sat Mar 2 14:15:34 UTC 2019


Author: tuexen
Date: Sat Mar  2 14:15:33 2019
New Revision: 344723
URL: https://svnweb.freebsd.org/changeset/base/344723

Log:
  Handle the case when calling the IPPROTO_SCTP level socket option
  SCTP_STATUS on an association with no primary path (early state).
  
  This issue was found by running syzkaller.
  
  MFC after:		3 days

Modified:
  head/sys/netinet/sctp_usrreq.c

Modified: head/sys/netinet/sctp_usrreq.c
==============================================================================
--- head/sys/netinet/sctp_usrreq.c	Sat Mar  2 13:16:01 2019	(r344722)
+++ head/sys/netinet/sctp_usrreq.c	Sat Mar  2 14:15:33 2019	(r344723)
@@ -2644,42 +2644,47 @@ flags_out:
 			sstat->sstat_instrms = stcb->asoc.streamincnt;
 			sstat->sstat_outstrms = stcb->asoc.streamoutcnt;
 			sstat->sstat_fragmentation_point = sctp_get_frag_point(stcb, &stcb->asoc);
-			memcpy(&sstat->sstat_primary.spinfo_address,
-			    &stcb->asoc.primary_destination->ro._l_addr,
-			    ((struct sockaddr *)(&stcb->asoc.primary_destination->ro._l_addr))->sa_len);
 			net = stcb->asoc.primary_destination;
-			((struct sockaddr_in *)&sstat->sstat_primary.spinfo_address)->sin_port = stcb->rport;
-			/*
-			 * Again the user can get info from sctp_constants.h
-			 * for what the state of the network is.
-			 */
-			if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
-				/* It's unconfirmed */
-				sstat->sstat_primary.spinfo_state = SCTP_UNCONFIRMED;
-			} else if (net->dest_state & SCTP_ADDR_REACHABLE) {
-				/* It's active */
-				sstat->sstat_primary.spinfo_state = SCTP_ACTIVE;
-			} else {
-				/* It's inactive */
-				sstat->sstat_primary.spinfo_state = SCTP_INACTIVE;
-			}
-			sstat->sstat_primary.spinfo_cwnd = net->cwnd;
-			sstat->sstat_primary.spinfo_srtt = net->lastsa >> SCTP_RTT_SHIFT;
-			sstat->sstat_primary.spinfo_rto = net->RTO;
-			sstat->sstat_primary.spinfo_mtu = net->mtu;
-			switch (stcb->asoc.primary_destination->ro._l_addr.sa.sa_family) {
+			if (net != NULL) {
+				memcpy(&sstat->sstat_primary.spinfo_address,
+				    &stcb->asoc.primary_destination->ro._l_addr,
+				    ((struct sockaddr *)(&stcb->asoc.primary_destination->ro._l_addr))->sa_len);
+				((struct sockaddr_in *)&sstat->sstat_primary.spinfo_address)->sin_port = stcb->rport;
+				/*
+				 * Again the user can get info from
+				 * sctp_constants.h for what the state of
+				 * the network is.
+				 */
+				if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
+					/* It's unconfirmed */
+					sstat->sstat_primary.spinfo_state = SCTP_UNCONFIRMED;
+				} else if (net->dest_state & SCTP_ADDR_REACHABLE) {
+					/* It's active */
+					sstat->sstat_primary.spinfo_state = SCTP_ACTIVE;
+				} else {
+					/* It's inactive */
+					sstat->sstat_primary.spinfo_state = SCTP_INACTIVE;
+				}
+				sstat->sstat_primary.spinfo_cwnd = net->cwnd;
+				sstat->sstat_primary.spinfo_srtt = net->lastsa >> SCTP_RTT_SHIFT;
+				sstat->sstat_primary.spinfo_rto = net->RTO;
+				sstat->sstat_primary.spinfo_mtu = net->mtu;
+				switch (stcb->asoc.primary_destination->ro._l_addr.sa.sa_family) {
 #if defined(INET)
-			case AF_INET:
-				sstat->sstat_primary.spinfo_mtu -= SCTP_MIN_V4_OVERHEAD;
-				break;
+				case AF_INET:
+					sstat->sstat_primary.spinfo_mtu -= SCTP_MIN_V4_OVERHEAD;
+					break;
 #endif
 #if defined(INET6)
-			case AF_INET6:
-				sstat->sstat_primary.spinfo_mtu -= SCTP_MIN_OVERHEAD;
-				break;
+				case AF_INET6:
+					sstat->sstat_primary.spinfo_mtu -= SCTP_MIN_OVERHEAD;
+					break;
 #endif
-			default:
-				break;
+				default:
+					break;
+				}
+			} else {
+				memset(&sstat->sstat_primary, 0, sizeof(struct sctp_paddrinfo));
 			}
 			sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb);
 			SCTP_TCB_UNLOCK(stcb);


More information about the svn-src-all mailing list