aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2020-05-10 17:19:19 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2020-05-10 17:19:19 +0000
commitefd5e69291940ae00eb5aaeac839926e78abb6ed (patch)
treed3fd2bb09e1a628ef9f7f2982bd6ebccf6ada63b
parent060a805b2f0aaa503e8fc2729e07c657d5ee24b2 (diff)
downloadsrc-efd5e69291940ae00eb5aaeac839926e78abb6ed.tar.gz
src-efd5e69291940ae00eb5aaeac839926e78abb6ed.zip
Ensure that we have a path when starting the T3 RXT timer.
Reported by: syzbot+f2321629047f89486fa3@syzkaller.appspotmail.com MFC after: 3 days
Notes
Notes: svn path=/head/; revision=360878
-rw-r--r--sys/netinet/sctp_asconf.c11
-rw-r--r--sys/netinet/sctp_indata.c14
-rw-r--r--sys/netinet/sctp_input.c29
-rw-r--r--sys/netinet/sctp_timer.c7
-rw-r--r--sys/netinet/sctputil.c13
5 files changed, 51 insertions, 23 deletions
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index 4617d57579ce..d54d708c90d8 100644
--- a/sys/netinet/sctp_asconf.c
+++ b/sys/netinet/sctp_asconf.c
@@ -1032,9 +1032,14 @@ sctp_assoc_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *dstnet)
(stcb->asoc.sent_queue_cnt > 0)) {
struct sctp_tmit_chunk *chk;
- chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
- sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
- stcb, chk->whoTo);
+ TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
+ if (chk->whoTo != NULL) {
+ break;
+ }
+ }
+ if (chk != NULL) {
+ sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo);
+ }
}
}
return;
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index 165418e27cca..00150a20f8ef 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -4439,7 +4439,12 @@ again:
}
}
}
- if (lchk) {
+ for (; lchk != NULL; lchk = TAILQ_NEXT(lchk, sctp_next)) {
+ if (lchk->whoTo != NULL) {
+ break;
+ }
+ }
+ if (lchk != NULL) {
/* Assure a timer is up */
sctp_timer_start(SCTP_TIMER_TYPE_SEND,
stcb->sctp_ep, stcb, lchk->whoTo);
@@ -5279,7 +5284,12 @@ again:
}
}
}
- if (lchk) {
+ for (; lchk != NULL; lchk = TAILQ_NEXT(lchk, sctp_next)) {
+ if (lchk->whoTo != NULL) {
+ break;
+ }
+ }
+ if (lchk != NULL) {
/* Assure a timer is up */
sctp_timer_start(SCTP_TIMER_TYPE_SEND,
stcb->sctp_ep, stcb, lchk->whoTo);
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 6eccf403dfbf..4b8d2a55c6ba 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -2956,6 +2956,7 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
{
/* cp must not be used, others call this without a c-ack :-) */
struct sctp_association *asoc;
+ struct sctp_tmit_chunk *chk;
SCTPDBG(SCTP_DEBUG_INPUT2,
"sctp_handle_cookie_ack: handling COOKIE-ACK\n");
@@ -3059,11 +3060,13 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
closed_socket:
/* Toss the cookie if I can */
sctp_toss_old_cookies(stcb, asoc);
- if (!TAILQ_EMPTY(&asoc->sent_queue)) {
- /* Restart the timer if we have pending data */
- struct sctp_tmit_chunk *chk;
-
- chk = TAILQ_FIRST(&asoc->sent_queue);
+ /* Restart the timer if we have pending data */
+ TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
+ if (chk->whoTo != NULL) {
+ break;
+ }
+ }
+ if (chk != NULL) {
sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo);
}
}
@@ -5159,6 +5162,7 @@ process_control_chunks:
} else {
struct mbuf *ret_buf;
struct sctp_inpcb *linp;
+ struct sctp_tmit_chunk *chk;
if (stcb) {
linp = NULL;
@@ -5220,14 +5224,13 @@ process_control_chunks:
got_auth = 1;
auth_skipped = 0;
}
- if (!TAILQ_EMPTY(&stcb->asoc.sent_queue)) {
- /*
- * Restart the timer if we have
- * pending data
- */
- struct sctp_tmit_chunk *chk;
-
- chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
+ /* Restart the timer if we have pending data */
+ TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
+ if (chk->whoTo != NULL) {
+ break;
+ }
+ }
+ if (chk != NULL) {
sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo);
}
}
diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c
index 3c27074b7d5a..22d2e0bfc3d2 100644
--- a/sys/netinet/sctp_timer.c
+++ b/sys/netinet/sctp_timer.c
@@ -974,7 +974,12 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
/* C3. See if we need to send a Fwd-TSN */
if (SCTP_TSN_GT(stcb->asoc.advanced_peer_ack_point, stcb->asoc.last_acked_seq)) {
send_forward_tsn(stcb, &stcb->asoc);
- if (lchk) {
+ for (; lchk != NULL; lchk = TAILQ_NEXT(lchk, sctp_next)) {
+ if (lchk->whoTo != NULL) {
+ break;
+ }
+ }
+ if (lchk != NULL) {
/* Assure a timer is up */
sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, lchk->whoTo);
}
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 543c57e0ecde..b757a2163dca 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -1841,14 +1841,19 @@ sctp_timeout_handler(void *t)
struct sctp_tmit_chunk *chk;
/*
- * safeguard. If there on some on the sent queue
+ * Safeguard. If there on some on the sent queue
* somewhere but no timers running something is
* wrong... so we start a timer on the first chunk
* on the send queue on whatever net it is sent to.
*/
- chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
- sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb,
- chk->whoTo);
+ TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
+ if (chk->whoTo != NULL) {
+ break;
+ }
+ }
+ if (chk != NULL) {
+ sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo);
+ }
}
break;
case SCTP_TIMER_TYPE_INIT: