svn commit: r209433 - releng/8.1/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Tue Jun 22 17:45:21 UTC 2010
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);
More information about the svn-src-all
mailing list