svn commit: r214389 - stable/8/sys/netinet
Randall Stewart
rrs at FreeBSD.org
Tue Oct 26 18:59:36 UTC 2010
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);
More information about the svn-src-all
mailing list