Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Oct 2010 18:59:36 +0000 (UTC)
From:      Randall Stewart <rrs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r214389 - stable/8/sys/netinet
Message-ID:  <201010261859.o9QIxaJZ062502@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rrs
Date: Tue Oct 26 18:59:36 2010
New Revision: 214389
URL: http://svn.freebsd.org/changeset/base/214389

Log:
  MFC of 209663
  This fixes a crash in SCTP. It was possible to have a
  large number of packets queued to a crashing process.
  In a specific case you may get 2 ABORT's back (from
  say two packets in flight). If the aborts happened to
  be processed at the same time its possible to have
  one free the association while the other is trying
  to report all the outbound packets. When this occured
  it could lead to a crash.

Modified:
  stable/8/sys/netinet/sctputil.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/netinet/sctputil.c
==============================================================================
--- stable/8/sys/netinet/sctputil.c	Tue Oct 26 18:56:55 2010	(r214388)
+++ stable/8/sys/netinet/sctputil.c	Tue Oct 26 18:59:36 2010	(r214389)
@@ -3691,6 +3691,10 @@ sctp_report_all_outbound(struct sctp_tcb
 	if (stcb == NULL) {
 		return;
 	}
+	if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+		/* already being freed */
+		return;
+	}
 	if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
 	    (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
 	    (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
@@ -3750,11 +3754,13 @@ sctp_report_all_outbound(struct sctp_tcb
 			stcb->asoc.stream_queue_cnt--;
 			TAILQ_REMOVE(&outs->outqueue, sp, next);
 			sctp_free_spbufspace(stcb, asoc, sp);
-			sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb,
-			    SCTP_NOTIFY_DATAGRAM_UNSENT, (void *)sp, so_locked);
 			if (sp->data) {
-				sctp_m_freem(sp->data);
-				sp->data = NULL;
+				sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb,
+				    SCTP_NOTIFY_DATAGRAM_UNSENT, (void *)sp, so_locked);
+				if (sp->data) {
+					sctp_m_freem(sp->data);
+					sp->data = NULL;
+				}
 			}
 			if (sp->net)
 				sctp_free_remote_addr(sp->net);



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