Author: tuexen
Date: Tue May 26 15:48:27 2020
New Revision: 361522
URL: https://svnweb.freebsd.org/changeset/base/361522

Log:
  MFS r361469: Fix bug in PR-SCTP
  Only drop DATA chunk with lower priorities as specified in RFC 7496.
  This issue was found by looking at a reproducer generated by syzkaller.
  
  MFS r361472: Improve SCTP iterator
  Ensure that the SCTP iterator runs with an stcb and inp, which belong to
  each other.
  
  MFS r361473: Improve stcb handling during teardown
  Ensure that an stcb is not dereferenced when it is about to be freed.
  This issue was found by SYZKALLER.
  
  MFS r361476: Improve ASCONF handling
  Avoid an integer underflow.
  
  Approved by:  re(gjb)

Modified:
  releng/11.4/sys/netinet/sctp_asconf.c
  releng/11.4/sys/netinet/sctp_indata.c
  releng/11.4/sys/netinet/sctp_indata.h
  releng/11.4/sys/netinet/sctp_output.c
  releng/11.4/sys/netinet/sctputil.c
Directory Properties:
  releng/11.4/   (props changed)

Modified: releng/11.4/sys/netinet/sctp_asconf.c
==============================================================================
--- releng/11.4/sys/netinet/sctp_asconf.c       Tue May 26 15:48:06 2020        
(r361521)
+++ releng/11.4/sys/netinet/sctp_asconf.c       Tue May 26 15:48:27 2020        
(r361522)
@@ -1797,9 +1797,9 @@ sctp_handle_asconf_ack(struct mbuf *m, int offset,
                }               /* switch */
 
                /* update remaining ASCONF-ACK message length to process */
-               ack_length -= SCTP_SIZE32(param_length);
-               if (ack_length <= 0) {
-                       /* no more data in the mbuf chain */
+               if (ack_length > SCTP_SIZE32(param_length)) {
+                       ack_length -= SCTP_SIZE32(param_length);
+               } else {
                        break;
                }
                offset += SCTP_SIZE32(param_length);

Modified: releng/11.4/sys/netinet/sctp_indata.c
==============================================================================
--- releng/11.4/sys/netinet/sctp_indata.c       Tue May 26 15:48:06 2020        
(r361521)
+++ releng/11.4/sys/netinet/sctp_indata.c       Tue May 26 15:48:27 2020        
(r361522)
@@ -162,6 +162,9 @@ sctp_build_readq_entry(struct sctp_tcb *stcb,
        read_queue_e->data = dm;
        read_queue_e->stcb = stcb;
        read_queue_e->port_from = stcb->rport;
+       if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+               read_queue_e->do_not_ref_stcb = 1;
+       }
 failed_build:
        return (read_queue_e);
 }
@@ -773,6 +776,7 @@ sctp_build_readq_entry_from_ctl(struct sctp_queued_to_
        atomic_add_int(&nc->whoFrom->ref_count, 1);
        nc->stcb = control->stcb;
        nc->port_from = control->port_from;
+       nc->do_not_ref_stcb = control->do_not_ref_stcb;
 }
 
 static void

Modified: releng/11.4/sys/netinet/sctp_indata.h
==============================================================================
--- releng/11.4/sys/netinet/sctp_indata.h       Tue May 26 15:48:06 2020        
(r361521)
+++ releng/11.4/sys/netinet/sctp_indata.h       Tue May 26 15:48:27 2020        
(r361522)
@@ -66,6 +66,9 @@ sctp_build_readq_entry(struct sctp_tcb *stcb,
                (_ctl)->data = dm; \
                (_ctl)->stcb = (in_it); \
                (_ctl)->port_from = (in_it)->rport; \
+               if ((in_it)->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { \
+                       (_ctl)->do_not_ref_stcb = 1; \
+               }\
        } \
 } while (0)
 

Modified: releng/11.4/sys/netinet/sctp_output.c
==============================================================================
--- releng/11.4/sys/netinet/sctp_output.c       Tue May 26 15:48:06 2020        
(r361521)
+++ releng/11.4/sys/netinet/sctp_output.c       Tue May 26 15:48:27 2020        
(r361522)
@@ -6198,11 +6198,11 @@ sctp_prune_prsctp(struct sctp_tcb *stcb,
                                 * This one is PR-SCTP AND buffer space
                                 * limited type
                                 */
-                               if (chk->rec.data.timetodrop.tv_sec >= 
(long)srcv->sinfo_timetolive) {
+                               if (chk->rec.data.timetodrop.tv_sec > 
(long)srcv->sinfo_timetolive) {
                                        /*
                                         * Lower numbers equates to higher
                                         * priority so if the one we are
-                                        * looking at has a larger or equal
+                                        * looking at has a larger
                                         * priority we want to drop the data
                                         * and NOT retransmit it.
                                         */
@@ -6233,7 +6233,7 @@ sctp_prune_prsctp(struct sctp_tcb *stcb,
                TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
                        /* Here we must move to the sent queue and mark */
                        if (PR_SCTP_BUF_ENABLED(chk->flags)) {
-                               if (chk->rec.data.timetodrop.tv_sec >= 
(long)srcv->sinfo_timetolive) {
+                               if (chk->rec.data.timetodrop.tv_sec > 
(long)srcv->sinfo_timetolive) {
                                        if (chk->data) {
                                                /*
                                                 * We release the book_size
@@ -12614,7 +12614,7 @@ sctp_lower_sosend(struct socket *so,
                top = SCTP_HEADER_TO_CHAIN(i_pak);
                sndlen = SCTP_HEADER_LEN(i_pak);
        }
-       SCTPDBG(SCTP_DEBUG_OUTPUT1, "Send called addr:%p send length %zu\n",
+       SCTPDBG(SCTP_DEBUG_OUTPUT1, "Send called addr:%p send length %zd\n",
            (void *)addr,
            sndlen);
        if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&

Modified: releng/11.4/sys/netinet/sctputil.c
==============================================================================
--- releng/11.4/sys/netinet/sctputil.c  Tue May 26 15:48:06 2020        
(r361521)
+++ releng/11.4/sys/netinet/sctputil.c  Tue May 26 15:48:27 2020        
(r361522)
@@ -1409,6 +1409,7 @@ select_a_new_ep:
                }
                tinp = it->inp;
                it->inp = LIST_NEXT(it->inp, sctp_list);
+               it->stcb = NULL;
                SCTP_INP_RUNLOCK(tinp);
                if (it->inp == NULL) {
                        goto done_with_iterator;
@@ -1478,6 +1479,9 @@ select_a_new_ep:
                        atomic_add_int(&it->stcb->asoc.refcnt, -1);
                        iteration_count = 0;
                }
+               KASSERT(it->inp == it->stcb->sctp_ep,
+                       ("%s: stcb %p does not belong to inp %p, but inp %p",
+                        __func__, it->stcb, it->inp, it->stcb->sctp_ep));
 
                /* run function on this one */
                (*it->function_assoc) (it->inp, it->stcb, it->pointer, it->val);
@@ -1510,6 +1514,7 @@ no_stcb:
        } else {
                it->inp = LIST_NEXT(it->inp, sctp_list);
        }
+       it->stcb = NULL;
        if (it->inp == NULL) {
                goto done_with_iterator;
        }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to