summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2011-02-13 14:48:11 +0000
committerrrs <rrs@FreeBSD.org>2011-02-13 14:48:11 +0000
commitabb9537f13f6654ace6780f8eb39100c4d4edd5b (patch)
treee3594b8cc57ed50ac8da620d0307c2c5c8d2aeef
parent333b3f42778aa1fe4ba3cbb94f4f84383fc7a34b (diff)
downloadFreeBSD-src-abb9537f13f6654ace6780f8eb39100c4d4edd5b.zip
FreeBSD-src-abb9537f13f6654ace6780f8eb39100c4d4edd5b.tar.gz
Fix a bug reported by Jonathan Leighton in his web-sctp testing
at the Univ-of-Del. Basically when a 1-to-1 socket did a socket/bind/send(data)/close. If the timing was right we would dereference a socket that is NULL. MFC after: 1 month
-rw-r--r--sys/netinet/sctp_input.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 016218b..39c9aa7 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -2865,24 +2865,31 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp,
SCTP_SOCKET_LOCK(so, 1);
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
- if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
- SCTP_SOCKET_UNLOCK(so, 1);
- return;
- }
#endif
- soisconnected(stcb->sctp_socket);
+ if ((stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) == 0) {
+ soisconnected(stcb->sctp_socket);
+ }
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
}
- sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
- stcb, net);
/*
* since we did not send a HB make sure we don't double
* things
*/
net->hb_responded = 1;
+ if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
+ /*
+ * We don't need to do the asconf thing, nor hb or
+ * autoclose if the socket is closed.
+ */
+ goto closed_socket;
+ }
+ sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
+ stcb, net);
+
+
if (stcb->asoc.sctp_autoclose_ticks &&
sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_AUTOCLOSE)) {
sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE,
@@ -2906,6 +2913,7 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp,
#endif
}
}
+closed_socket:
/* Toss the cookie if I can */
sctp_toss_old_cookies(stcb, asoc);
if (!TAILQ_EMPTY(&asoc->sent_queue)) {
OpenPOWER on IntegriCloud