Author: tuexen
Date: Sun May 10 17:19:19 2020
New Revision: 360878
URL: https://svnweb.freebsd.org/changeset/base/360878

Log:
  Ensure that we have a path when starting the T3 RXT timer.
  
  Reported by:  syzbot+f2321629047f89486...@syzkaller.appspotmail.com
  MFC after:    3 days

Modified:
  head/sys/netinet/sctp_asconf.c
  head/sys/netinet/sctp_indata.c
  head/sys/netinet/sctp_input.c
  head/sys/netinet/sctp_timer.c
  head/sys/netinet/sctputil.c

Modified: head/sys/netinet/sctp_asconf.c
==============================================================================
--- head/sys/netinet/sctp_asconf.c      Sun May 10 16:11:19 2020        
(r360877)
+++ head/sys/netinet/sctp_asconf.c      Sun May 10 17:19:19 2020        
(r360878)
@@ -1032,9 +1032,14 @@ sctp_assoc_immediate_retrans(struct sctp_tcb *stcb, st
                    (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;

Modified: head/sys/netinet/sctp_indata.c
==============================================================================
--- head/sys/netinet/sctp_indata.c      Sun May 10 16:11:19 2020        
(r360877)
+++ head/sys/netinet/sctp_indata.c      Sun May 10 17:19:19 2020        
(r360878)
@@ -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);

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c       Sun May 10 16:11:19 2020        
(r360877)
+++ head/sys/netinet/sctp_input.c       Sun May 10 17:19:19 2020        
(r360878)
@@ -2956,6 +2956,7 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *c
 {
        /* 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 *c
 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);
                                }
                        }

Modified: head/sys/netinet/sctp_timer.c
==============================================================================
--- head/sys/netinet/sctp_timer.c       Sun May 10 16:11:19 2020        
(r360877)
+++ head/sys/netinet/sctp_timer.c       Sun May 10 17:19:19 2020        
(r360878)
@@ -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);
                        }

Modified: head/sys/netinet/sctputil.c
==============================================================================
--- head/sys/netinet/sctputil.c Sun May 10 16:11:19 2020        (r360877)
+++ head/sys/netinet/sctputil.c Sun May 10 17:19:19 2020        (r360878)
@@ -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:
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to