Ensure that we have a path when starting the T3 RXT timer.

Reported by:	syzbot+f2321629047f89486fa3@syzkaller.appspotmail.com
MFC after:	3 days
This commit is contained in:
Michael Tuexen 2020-05-10 17:19:19 +00:00
parent 060a805b2f
commit efd5e69291
5 changed files with 51 additions and 23 deletions

View File

@ -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;

View File

@ -4439,7 +4439,12 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
}
}
}
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 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
}
}
}
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);

View File

@ -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 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
} else {
struct mbuf *ret_buf;
struct sctp_inpcb *linp;
struct sctp_tmit_chunk *chk;
if (stcb) {
linp = NULL;
@ -5220,14 +5224,13 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
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);
}
}

View File

@ -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);
}

View File

@ -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: