Date: Tue, 22 Jun 2010 17:45:21 +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: r209433 - releng/8.1/sys/netinet Message-ID: <201006221745.o5MHjLGu013167@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: tuexen Date: Tue Jun 22 17:45:21 2010 New Revision: 209433 URL: http://svn.freebsd.org/changeset/base/209433 Log: MFC 209264 * Fix a bug where the length of the ASCONF-ACK was calculated wrong due to using an uninitialized variable. * Fix a bug where a NULL pointer was dereferenced when interfaces come and go at a high rate. * Fix a bug where inps where not deregistered from iterators. * Fix a race condition in freeing an association. * Fix a refcount problem related to the iterator. Each of the above bug results in a panic. It shows up when interfaces come and go at a high rate. Approved by: re Modified: releng/8.1/sys/netinet/sctp_asconf.c releng/8.1/sys/netinet/sctp_pcb.c Directory Properties: releng/8.1/sys/ (props changed) releng/8.1/sys/amd64/include/xen/ (props changed) releng/8.1/sys/cddl/contrib/opensolaris/ (props changed) releng/8.1/sys/contrib/dev/acpica/ (props changed) releng/8.1/sys/contrib/pf/ (props changed) releng/8.1/sys/dev/xen/xenpci/ (props changed) releng/8.1/sys/geom/sched/ (props changed) Modified: releng/8.1/sys/netinet/sctp_asconf.c ============================================================================== --- releng/8.1/sys/netinet/sctp_asconf.c Tue Jun 22 16:20:10 2010 (r209432) +++ releng/8.1/sys/netinet/sctp_asconf.c Tue Jun 22 17:45:21 2010 (r209433) @@ -826,6 +826,7 @@ send_reply: ack->serial_number = serial_num; ack->last_sent_to = NULL; ack->data = m_ack; + ack->len = 0; n = m_ack; while (n) { ack->len += SCTP_BUF_LEN(n); @@ -1025,7 +1026,8 @@ sctp_asconf_nets_cleanup(struct sctp_tcb * address. */ if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro) && - SCTP_GET_IF_INDEX_FROM_ROUTE(&net->ro) != ifn->ifn_index) { + ((ifn == NULL) || + (SCTP_GET_IF_INDEX_FROM_ROUTE(&net->ro) != ifn->ifn_index))) { /* clear any cached route */ RTFREE(net->ro.ro_rt); net->ro.ro_rt = NULL; Modified: releng/8.1/sys/netinet/sctp_pcb.c ============================================================================== --- releng/8.1/sys/netinet/sctp_pcb.c Tue Jun 22 16:20:10 2010 (r209432) +++ releng/8.1/sys/netinet/sctp_pcb.c Tue Jun 22 17:45:21 2010 (r209433) @@ -3074,6 +3074,9 @@ sctp_iterator_inp_being_freed(struct sct SCTP_FREE(it, SCTP_M_ITER); } else { it->inp = LIST_NEXT(it->inp, sctp_list); + if (it->inp) { + SCTP_INP_INCR_REF(it->inp); + } } /* * When its put in the refcnt is incremented so decr @@ -3114,17 +3117,10 @@ sctp_inpcb_free(struct sctp_inpcb *inp, #ifdef SCTP_LOG_CLOSING sctp_log_closing(inp, NULL, 0); #endif - if (from == SCTP_CALLED_AFTER_CMPSET_OFCLOSE) { - /* - * Once we are in we can remove the flag from = 1 is only - * passed from the actual closing routines that are called - * via the sockets layer. - */ - SCTP_ITERATOR_LOCK(); - /* mark any iterators on the list or being processed */ - sctp_iterator_inp_being_freed(inp); - SCTP_ITERATOR_UNLOCK(); - } + SCTP_ITERATOR_LOCK(); + /* mark any iterators on the list or being processed */ + sctp_iterator_inp_being_freed(inp); + SCTP_ITERATOR_UNLOCK(); so = inp->sctp_socket; if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) { /* been here before.. eeks.. get out of here */ @@ -4637,7 +4633,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, atomic_add_int(&stcb->asoc.refcnt, 1); SCTP_TCB_UNLOCK(stcb); - SCTP_INP_INFO_WLOCK(); SCTP_INP_WLOCK(inp); SCTP_TCB_LOCK(stcb); @@ -4680,6 +4675,16 @@ sctp_free_assoc(struct sctp_inpcb *inp, if (from_inpcbfree == SCTP_NORMAL_PROC) { atomic_add_int(&stcb->asoc.refcnt, -1); } + if (stcb->asoc.refcnt) { + stcb->asoc.state &= ~SCTP_STATE_IN_ACCEPT_QUEUE; + sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL); + if (from_inpcbfree == SCTP_NORMAL_PROC) { + SCTP_INP_INFO_WUNLOCK(); + SCTP_INP_WUNLOCK(inp); + } + SCTP_TCB_UNLOCK(stcb); + return (0); + } asoc->state = 0; if (inp->sctp_tcbhash) { LIST_REMOVE(stcb, sctp_tcbhash);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201006221745.o5MHjLGu013167>