From 478fbccb67af2f618791dcc64bab9840a4e26279 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Sat, 3 Jul 2010 14:03:31 +0000 Subject: [PATCH] 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. MFC after: 3 days --- sys/netinet/sctputil.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 9a8f32f7cf2..e390fb1cde2 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -3694,6 +3694,10 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked 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)) { @@ -3753,11 +3757,13 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked 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); -- 2.45.2