diff options
author | Michael Tuexen <tuexen@FreeBSD.org> | 2020-05-10 17:19:19 +0000 |
---|---|---|
committer | Michael Tuexen <tuexen@FreeBSD.org> | 2020-05-10 17:19:19 +0000 |
commit | efd5e69291940ae00eb5aaeac839926e78abb6ed (patch) | |
tree | d3fd2bb09e1a628ef9f7f2982bd6ebccf6ada63b | |
parent | 060a805b2f0aaa503e8fc2729e07c657d5ee24b2 (diff) | |
download | src-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.c | 11 | ||||
-rw-r--r-- | sys/netinet/sctp_indata.c | 14 | ||||
-rw-r--r-- | sys/netinet/sctp_input.c | 29 | ||||
-rw-r--r-- | sys/netinet/sctp_timer.c | 7 | ||||
-rw-r--r-- | sys/netinet/sctputil.c | 13 |
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: |