Author: tuexen
Date: Wed Jul  1 20:09:34 2020
New Revision: 362858
URL: https://svnweb.freebsd.org/changeset/base/362858

Log:
  MFC r354774:
  Add boundary and overflow checks to the formulas used in the TCP CUBIC
  congestion control module.
  
  Submitted by:         rscheff
  Reviewed by:          rgrimes
  Differential Revision:        https://reviews.freebsd.org/D19118

Modified:
  stable/12/sys/netinet/cc/cc_cubic.c
  stable/12/sys/netinet/cc/cc_cubic.h
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/netinet/cc/cc_cubic.c
==============================================================================
--- stable/12/sys/netinet/cc/cc_cubic.c Wed Jul  1 19:50:03 2020        
(r362857)
+++ stable/12/sys/netinet/cc/cc_cubic.c Wed Jul  1 20:09:34 2020        
(r362858)
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
+#include <sys/limits.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/socket.h>
@@ -144,7 +145,14 @@ cubic_ack_received(struct cc_var *ccv, uint16_t type)
                        cubic_data->flags |= CUBICFLAG_IN_SLOWSTART;
                        newreno_cc_algo.ack_received(ccv, type);
                } else {
-                       ticks_since_cong = ticks - cubic_data->t_last_cong;
+                       if ((ticks_since_cong =
+                           ticks - cubic_data->t_last_cong) < 0) {
+                               /*
+                                * dragging t_last_cong along
+                                */
+                               ticks_since_cong = INT_MAX;
+                               cubic_data->t_last_cong = ticks - INT_MAX;
+                       }
 
                        if (cubic_data->flags & (CUBICFLAG_IN_SLOWSTART |
                                                 CUBICFLAG_IN_APPLIMIT)) {
@@ -170,12 +178,14 @@ cubic_ack_received(struct cc_var *ccv, uint16_t type)
 
                        ccv->flags &= ~CCF_ABC_SENTAWND;
 
-                       if (w_cubic_next < w_tf)
+                       if (w_cubic_next < w_tf) {
                                /*
                                 * TCP-friendly region, follow tf
                                 * cwnd growth.
                                 */
-                               CCV(ccv, snd_cwnd) = w_tf;
+                               if (CCV(ccv, snd_cwnd) < w_tf)
+                                       CCV(ccv, snd_cwnd) = ulmin(w_tf, 
INT_MAX);
+                       }
 
                        else if (CCV(ccv, snd_cwnd) < w_cubic_next) {
                                /*
@@ -183,12 +193,14 @@ cubic_ack_received(struct cc_var *ccv, uint16_t type)
                                 * cwnd growth.
                                 */
                                if (V_tcp_do_rfc3465)
-                                       CCV(ccv, snd_cwnd) = w_cubic_next;
+                                       CCV(ccv, snd_cwnd) = ulmin(w_cubic_next,
+                                           INT_MAX);
                                else
-                                       CCV(ccv, snd_cwnd) += ((w_cubic_next -
+                                       CCV(ccv, snd_cwnd) += ulmax(1,
+                                           ((ulmin(w_cubic_next, INT_MAX) -
                                            CCV(ccv, snd_cwnd)) *
                                            CCV(ccv, t_maxseg)) /
-                                           CCV(ccv, snd_cwnd);
+                                           CCV(ccv, snd_cwnd));
                        }
 
                        /*

Modified: stable/12/sys/netinet/cc/cc_cubic.h
==============================================================================
--- stable/12/sys/netinet/cc/cc_cubic.h Wed Jul  1 19:50:03 2020        
(r362857)
+++ stable/12/sys/netinet/cc/cc_cubic.h Wed Jul  1 20:09:34 2020        
(r362858)
@@ -41,6 +41,8 @@
 #ifndef _NETINET_CC_CUBIC_H_
 #define _NETINET_CC_CUBIC_H_
 
+#include <sys/limits.h>
+
 /* Number of bits of precision for fixed point math calcs. */
 #define        CUBIC_SHIFT             8
 
@@ -70,6 +72,12 @@
 /* Don't trust s_rtt until this many rtt samples have been taken. */
 #define        CUBIC_MIN_RTT_SAMPLES   8
 
+/*
+ * (2^21)^3 is long max. Dividing (2^63) by Cubic_C_factor
+ * and taking cube-root yields 448845 as the effective useful limit
+ */
+#define        CUBED_ROOT_MAX_ULONG    448845
+
 /* Userland only bits. */
 #ifndef _KERNEL
 
@@ -172,8 +180,13 @@ cubic_cwnd(int ticks_since_cong, unsigned long wmax, u
        /* K is in fixed point form with CUBIC_SHIFT worth of precision. */
 
        /* t - K, with CUBIC_SHIFT worth of precision. */
-       cwnd = ((int64_t)(ticks_since_cong << CUBIC_SHIFT) - (K * hz)) / hz;
+       cwnd = (((int64_t)ticks_since_cong << CUBIC_SHIFT) - (K * hz)) / hz;
 
+       if (cwnd > CUBED_ROOT_MAX_ULONG)
+               return INT_MAX;
+       if (cwnd < -CUBED_ROOT_MAX_ULONG)
+               return 0;
+
        /* (t - K)^3, with CUBIC_SHIFT^3 worth of precision. */
        cwnd *= (cwnd * cwnd);
 
@@ -183,9 +196,13 @@ cubic_cwnd(int ticks_since_cong, unsigned long wmax, u
         * CUBIC_SHIFT included in the value. 3 from the cubing of cwnd above,
         * and an extra from multiplying through by CUBIC_C_FACTOR.
         */
-       cwnd = ((cwnd * CUBIC_C_FACTOR * smss) >> CUBIC_SHIFT_4) + wmax;
 
-       return ((unsigned long)cwnd);
+       cwnd = ((cwnd * CUBIC_C_FACTOR) >> CUBIC_SHIFT_4) * smss + wmax;
+
+       /*
+        * for negative cwnd, limiting to zero as lower bound
+        */
+       return (lmax(0,cwnd));
 }
 
 /*
@@ -223,8 +240,10 @@ tf_cwnd(int ticks_since_cong, int rtt_ticks, unsigned 
 {
 
        /* Equation 4 of I-D. */
-       return (((wmax * CUBIC_BETA) + (((THREE_X_PT3 * ticks_since_cong *
-           smss) << CUBIC_SHIFT) / TWO_SUB_PT3 / rtt_ticks)) >> CUBIC_SHIFT);
+       return (((wmax * CUBIC_BETA) +
+           (((THREE_X_PT3 * (unsigned long)ticks_since_cong *
+           (unsigned long)smss) << CUBIC_SHIFT) / (TWO_SUB_PT3 * rtt_ticks)))
+           >> CUBIC_SHIFT);
 }
 
 #endif /* _NETINET_CC_CUBIC_H_ */
_______________________________________________
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