Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Aug 2020 22:26:38 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r364574 - stable/12/sys/netinet
Message-ID:  <202008232226.07NMQcFf099160@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Sun Aug 23 22:26:38 2020
New Revision: 364574
URL: https://svnweb.freebsd.org/changeset/base/364574

Log:
  MFC r359405:
  Handle integer overflows correctly when converting msecs and secs to
  ticks and vice versa.
  These issues were caught by recently added panic() calls on INVARIANTS
  systems.

Modified:
  stable/12/sys/netinet/sctp_cc_functions.c
  stable/12/sys/netinet/sctp_constants.h
  stable/12/sys/netinet/sctp_input.c
  stable/12/sys/netinet/sctp_pcb.c
  stable/12/sys/netinet/sctp_timer.c
  stable/12/sys/netinet/sctp_usrreq.c
  stable/12/sys/netinet/sctputil.c
  stable/12/sys/netinet/sctputil.h
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/netinet/sctp_cc_functions.c
==============================================================================
--- stable/12/sys/netinet/sctp_cc_functions.c	Sun Aug 23 22:24:46 2020	(r364573)
+++ stable/12/sys/netinet/sctp_cc_functions.c	Sun Aug 23 22:26:38 2020	(r364574)
@@ -1914,7 +1914,7 @@ measure_rtt(struct sctp_nets *net)
 	if (net->fast_retran_ip == 0 && net->ssthresh < 0xFFFF && htcp_ccount(&net->cc_mod.htcp_ca) > 3) {
 		if (net->cc_mod.htcp_ca.maxRTT < net->cc_mod.htcp_ca.minRTT)
 			net->cc_mod.htcp_ca.maxRTT = net->cc_mod.htcp_ca.minRTT;
-		if (net->cc_mod.htcp_ca.maxRTT < srtt && srtt <= net->cc_mod.htcp_ca.maxRTT + MSEC_TO_TICKS(20))
+		if (net->cc_mod.htcp_ca.maxRTT < srtt && srtt <= net->cc_mod.htcp_ca.maxRTT + sctp_msecs_to_ticks(20))
 			net->cc_mod.htcp_ca.maxRTT = srtt;
 	}
 }
@@ -1975,7 +1975,7 @@ htcp_beta_update(struct htcp *ca, uint32_t minRTT, uin
 		}
 	}
 
-	if (ca->modeswitch && minRTT > (uint32_t)MSEC_TO_TICKS(10) && maxRTT) {
+	if (ca->modeswitch && minRTT > sctp_msecs_to_ticks(10) && maxRTT) {
 		ca->beta = (minRTT << 7) / maxRTT;
 		if (ca->beta < BETA_MIN)
 			ca->beta = BETA_MIN;

Modified: stable/12/sys/netinet/sctp_constants.h
==============================================================================
--- stable/12/sys/netinet/sctp_constants.h	Sun Aug 23 22:24:46 2020	(r364573)
+++ stable/12/sys/netinet/sctp_constants.h	Sun Aug 23 22:26:38 2020	(r364574)
@@ -577,16 +577,6 @@ __FBSDID("$FreeBSD$");
 #define SCTP_ASOC_MAX_CHUNKS_ON_QUEUE 512
 
 
-/* The conversion from time to ticks and vice versa is done by rounding
- * upwards. This way we can test in the code the time to be positive and
- * know that this corresponds to a positive number of ticks.
- */
-#define MSEC_TO_TICKS(x) ((hz == 1000) ? x : ((((x) * hz) + 999) / 1000))
-#define TICKS_TO_MSEC(x) ((hz == 1000) ? x : ((((x) * 1000) + (hz - 1)) / hz))
-
-#define SEC_TO_TICKS(x) ((x) * hz)
-#define TICKS_TO_SEC(x) (((x) + (hz - 1)) / hz)
-
 /*
  * Basically the minimum amount of time before I do a early FR. Making this
  * value to low will cause duplicate retransmissions.

Modified: stable/12/sys/netinet/sctp_input.c
==============================================================================
--- stable/12/sys/netinet/sctp_input.c	Sun Aug 23 22:24:46 2020	(r364573)
+++ stable/12/sys/netinet/sctp_input.c	Sun Aug 23 22:26:38 2020	(r364574)
@@ -2600,7 +2600,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, in
 	 */
 	(void)SCTP_GETTIME_TIMEVAL(&now);
 	/* Expire time is in Ticks, so we convert to seconds */
-	time_expires.tv_sec = cookie->time_entered.tv_sec + TICKS_TO_SEC(cookie->cookie_life);
+	time_expires.tv_sec = cookie->time_entered.tv_sec + sctp_ticks_to_secs(cookie->cookie_life);
 	time_expires.tv_usec = cookie->time_entered.tv_usec;
 	if (timevalcmp(&now, &time_expires, >)) {
 		/* cookie is stale! */

Modified: stable/12/sys/netinet/sctp_pcb.c
==============================================================================
--- stable/12/sys/netinet/sctp_pcb.c	Sun Aug 23 22:24:46 2020	(r364573)
+++ stable/12/sys/netinet/sctp_pcb.c	Sun Aug 23 22:26:38 2020	(r364574)
@@ -2553,13 +2553,13 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
 	m = &inp->sctp_ep;
 
 	/* setup the base timeout information */
-	m->sctp_timeoutticks[SCTP_TIMER_SEND] = SEC_TO_TICKS(SCTP_SEND_SEC);	/* needed ? */
-	m->sctp_timeoutticks[SCTP_TIMER_INIT] = SEC_TO_TICKS(SCTP_INIT_SEC);	/* needed ? */
-	m->sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_delayed_sack_time_default));
-	m->sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_heartbeat_interval_default));
-	m->sctp_timeoutticks[SCTP_TIMER_PMTU] = SEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_pmtu_raise_time_default));
-	m->sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] = SEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_shutdown_guard_time_default));
-	m->sctp_timeoutticks[SCTP_TIMER_SIGNATURE] = SEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_secret_lifetime_default));
+	m->sctp_timeoutticks[SCTP_TIMER_SEND] = sctp_secs_to_ticks(SCTP_SEND_SEC);	/* needed ? */
+	m->sctp_timeoutticks[SCTP_TIMER_INIT] = sctp_secs_to_ticks(SCTP_INIT_SEC);	/* needed ? */
+	m->sctp_timeoutticks[SCTP_TIMER_RECV] = sctp_msecs_to_ticks(SCTP_BASE_SYSCTL(sctp_delayed_sack_time_default));
+	m->sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_msecs_to_ticks(SCTP_BASE_SYSCTL(sctp_heartbeat_interval_default));
+	m->sctp_timeoutticks[SCTP_TIMER_PMTU] = sctp_secs_to_ticks(SCTP_BASE_SYSCTL(sctp_pmtu_raise_time_default));
+	m->sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] = sctp_secs_to_ticks(SCTP_BASE_SYSCTL(sctp_shutdown_guard_time_default));
+	m->sctp_timeoutticks[SCTP_TIMER_SIGNATURE] = sctp_secs_to_ticks(SCTP_BASE_SYSCTL(sctp_secret_lifetime_default));
 	/* all max/min max are in ms */
 	m->sctp_maxrto = SCTP_BASE_SYSCTL(sctp_rto_max_default);
 	m->sctp_minrto = SCTP_BASE_SYSCTL(sctp_rto_min_default);
@@ -2607,7 +2607,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
 	sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL);
 
 	/* How long is a cookie good for ? */
-	m->def_cookie_life = MSEC_TO_TICKS(SCTP_BASE_SYSCTL(sctp_valid_cookie_life_default));
+	m->def_cookie_life = sctp_msecs_to_ticks(SCTP_BASE_SYSCTL(sctp_valid_cookie_life_default));
 	/*
 	 * Initialize authentication parameters
 	 */

Modified: stable/12/sys/netinet/sctp_timer.c
==============================================================================
--- stable/12/sys/netinet/sctp_timer.c	Sun Aug 23 22:24:46 2020	(r364573)
+++ stable/12/sys/netinet/sctp_timer.c	Sun Aug 23 22:26:38 2020	(r364574)
@@ -1539,7 +1539,7 @@ sctp_autoclose_timer(struct sctp_inpcb *inp, struct sc
 			tim_touse = &asoc->time_last_sent;
 		}
 		/* Now has long enough transpired to autoclose? */
-		ticks_gone_by = SEC_TO_TICKS((uint32_t)(tn.tv_sec - tim_touse->tv_sec));
+		ticks_gone_by = sctp_secs_to_ticks((uint32_t)(tn.tv_sec - tim_touse->tv_sec));
 		if (ticks_gone_by >= asoc->sctp_autoclose_ticks) {
 			/*
 			 * autoclose time has hit, call the output routine,

Modified: stable/12/sys/netinet/sctp_usrreq.c
==============================================================================
--- stable/12/sys/netinet/sctp_usrreq.c	Sun Aug 23 22:24:46 2020	(r364573)
+++ stable/12/sys/netinet/sctp_usrreq.c	Sun Aug 23 22:26:38 2020	(r364574)
@@ -1581,7 +1581,7 @@ sctp_getopt(struct socket *so, int optname, void *optv
 			break;
 		case SCTP_AUTOCLOSE:
 			if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE))
-				val = TICKS_TO_SEC(inp->sctp_ep.auto_close_time);
+				val = sctp_ticks_to_secs(inp->sctp_ep.auto_close_time);
 			else
 				val = 0;
 			break;
@@ -1993,7 +1993,7 @@ flags_out:
 				    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
 				    (sack->sack_assoc_id == SCTP_FUTURE_ASSOC))) {
 					SCTP_INP_RLOCK(inp);
-					sack->sack_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
+					sack->sack_delay = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
 					sack->sack_freq = inp->sctp_ep.sctp_sack_freq;
 					SCTP_INP_RUNLOCK(inp);
 				} else {
@@ -2474,7 +2474,7 @@ flags_out:
 					/* Use endpoint defaults */
 					SCTP_INP_RLOCK(inp);
 					paddrp->spp_pathmaxrxt = inp->sctp_ep.def_net_failure;
-					paddrp->spp_hbinterval = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
+					paddrp->spp_hbinterval = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
 					paddrp->spp_assoc_id = SCTP_FUTURE_ASSOC;
 					/* get inp's default */
 					if (inp->sctp_ep.default_dscp & 0x01) {
@@ -2746,7 +2746,7 @@ flags_out:
 			SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id);
 
 			if (stcb) {
-				sasoc->sasoc_cookie_life = TICKS_TO_MSEC(stcb->asoc.cookie_life);
+				sasoc->sasoc_cookie_life = sctp_ticks_to_msecs(stcb->asoc.cookie_life);
 				sasoc->sasoc_asocmaxrxt = stcb->asoc.max_send_times;
 				sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets;
 				sasoc->sasoc_peer_rwnd = stcb->asoc.peers_rwnd;
@@ -2758,7 +2758,7 @@ flags_out:
 				    ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
 				    (sasoc->sasoc_assoc_id == SCTP_FUTURE_ASSOC))) {
 					SCTP_INP_RLOCK(inp);
-					sasoc->sasoc_cookie_life = TICKS_TO_MSEC(inp->sctp_ep.def_cookie_life);
+					sasoc->sasoc_cookie_life = sctp_ticks_to_msecs(inp->sctp_ep.def_cookie_life);
 					sasoc->sasoc_asocmaxrxt = inp->sctp_ep.max_send_times;
 					sasoc->sasoc_number_peer_destinations = 0;
 					sasoc->sasoc_peer_rwnd = 0;
@@ -3836,7 +3836,7 @@ sctp_setopt(struct socket *so, int optname, void *optv
 			 * The value is in ticks. Note this does not effect
 			 * old associations, only new ones.
 			 */
-			inp->sctp_ep.auto_close_time = SEC_TO_TICKS(*mopt);
+			inp->sctp_ep.auto_close_time = sctp_secs_to_ticks(*mopt);
 			break;
 		}
 		SCTP_INP_WLOCK(inp);
@@ -4233,10 +4233,12 @@ sctp_setopt(struct socket *so, int optname, void *optv
 			SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, optsize);
 			SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id);
 			if (sack->sack_delay) {
-				if (sack->sack_delay > SCTP_MAX_SACK_DELAY)
-					sack->sack_delay = SCTP_MAX_SACK_DELAY;
-				if (MSEC_TO_TICKS(sack->sack_delay) < 1) {
-					sack->sack_delay = TICKS_TO_MSEC(1);
+				if (sack->sack_delay > SCTP_MAX_SACK_DELAY) {
+					error = EINVAL;
+					if (stcb != NULL) {
+						SCTP_TCB_UNLOCK(stcb);
+					}
+					break;
 				}
 			}
 			if (stcb) {
@@ -4255,7 +4257,7 @@ sctp_setopt(struct socket *so, int optname, void *optv
 				    (sack->sack_assoc_id == SCTP_ALL_ASSOC)))) {
 					SCTP_INP_WLOCK(inp);
 					if (sack->sack_delay) {
-						inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = MSEC_TO_TICKS(sack->sack_delay);
+						inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = sctp_msecs_to_ticks(sack->sack_delay);
 					}
 					if (sack->sack_freq) {
 						inp->sctp_ep.sctp_sack_freq = sack->sack_freq;
@@ -5618,14 +5620,14 @@ sctp_setopt(struct socket *so, int optname, void *optv
 					else if (paddrp->spp_hbinterval != 0) {
 						if (paddrp->spp_hbinterval > SCTP_MAX_HB_INTERVAL)
 							paddrp->spp_hbinterval = SCTP_MAX_HB_INTERVAL;
-						inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(paddrp->spp_hbinterval);
+						inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_msecs_to_ticks(paddrp->spp_hbinterval);
 					}
 
 					if (paddrp->spp_flags & SPP_HB_ENABLE) {
 						if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
 							inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0;
 						} else if (paddrp->spp_hbinterval) {
-							inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = MSEC_TO_TICKS(paddrp->spp_hbinterval);
+							inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_msecs_to_ticks(paddrp->spp_hbinterval);
 						}
 						sctp_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
 					} else if (paddrp->spp_flags & SPP_HB_DISABLE) {
@@ -5740,7 +5742,7 @@ sctp_setopt(struct socket *so, int optname, void *optv
 				if (sasoc->sasoc_asocmaxrxt)
 					stcb->asoc.max_send_times = sasoc->sasoc_asocmaxrxt;
 				if (sasoc->sasoc_cookie_life) {
-					stcb->asoc.cookie_life = MSEC_TO_TICKS(sasoc->sasoc_cookie_life);
+					stcb->asoc.cookie_life = sctp_msecs_to_ticks(sasoc->sasoc_cookie_life);
 				}
 				SCTP_TCB_UNLOCK(stcb);
 			} else {
@@ -5752,7 +5754,7 @@ sctp_setopt(struct socket *so, int optname, void *optv
 					if (sasoc->sasoc_asocmaxrxt)
 						inp->sctp_ep.max_send_times = sasoc->sasoc_asocmaxrxt;
 					if (sasoc->sasoc_cookie_life) {
-						inp->sctp_ep.def_cookie_life = MSEC_TO_TICKS(sasoc->sasoc_cookie_life);
+						inp->sctp_ep.def_cookie_life = sctp_msecs_to_ticks(sasoc->sasoc_cookie_life);
 					}
 					SCTP_INP_WUNLOCK(inp);
 				} else {

Modified: stable/12/sys/netinet/sctputil.c
==============================================================================
--- stable/12/sys/netinet/sctputil.c	Sun Aug 23 22:24:46 2020	(r364573)
+++ stable/12/sys/netinet/sctputil.c	Sun Aug 23 22:26:38 2020	(r364574)
@@ -773,6 +773,80 @@ sctp_audit_log(uint8_t ev, uint8_t fd)
 #endif
 
 /*
+ * The conversion from time to ticks and vice versa is done by rounding
+ * upwards. This way we can test in the code the time to be positive and
+ * know that this corresponds to a positive number of ticks.
+ */
+
+uint32_t
+sctp_msecs_to_ticks(uint32_t msecs)
+{
+	uint64_t temp;
+	uint32_t ticks;
+
+	if (hz == 1000) {
+		ticks = msecs;
+	} else {
+		temp = (((uint64_t)msecs * hz) + 999) / 1000;
+		if (temp > UINT32_MAX) {
+			ticks = UINT32_MAX;
+		} else {
+			ticks = (uint32_t)temp;
+		}
+	}
+	return (ticks);
+}
+
+uint32_t
+sctp_ticks_to_msecs(uint32_t ticks)
+{
+	uint64_t temp;
+	uint32_t msecs;
+
+	if (hz == 1000) {
+		msecs = ticks;
+	} else {
+		temp = (((uint64_t)ticks * 1000) + (hz - 1)) / hz;
+		if (temp > UINT32_MAX) {
+			msecs = UINT32_MAX;
+		} else {
+			msecs = (uint32_t)temp;
+		}
+	}
+	return (msecs);
+}
+
+uint32_t
+sctp_secs_to_ticks(uint32_t secs)
+{
+	uint64_t temp;
+	uint32_t ticks;
+
+	temp = (uint64_t)secs * hz;
+	if (temp > UINT32_MAX) {
+		ticks = UINT32_MAX;
+	} else {
+		ticks = (uint32_t)temp;
+	}
+	return (ticks);
+}
+
+uint32_t
+sctp_ticks_to_secs(uint32_t ticks)
+{
+	uint64_t temp;
+	uint32_t secs;
+
+	temp = ((uint64_t)ticks + (hz - 1)) / hz;
+	if (temp > UINT32_MAX) {
+		secs = UINT32_MAX;
+	} else {
+		secs = (uint32_t)temp;
+	}
+	return (secs);
+}
+
+/*
  * sctp_stop_timers_for_shutdown() should be called
  * when entering the SHUTDOWN_SENT or SHUTDOWN_ACK_SENT
  * state to make sure that all timers are stopped.
@@ -1065,7 +1139,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb
 	SCTP_SET_STATE(stcb, SCTP_STATE_INUSE);
 	asoc->max_burst = inp->sctp_ep.max_burst;
 	asoc->fr_max_burst = inp->sctp_ep.fr_max_burst;
-	asoc->heart_beat_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
+	asoc->heart_beat_delay = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
 	asoc->cookie_life = inp->sctp_ep.def_cookie_life;
 	asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off;
 	asoc->ecn_supported = inp->ecn_supported;
@@ -1151,7 +1225,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb
 	asoc->context = inp->sctp_context;
 	asoc->local_strreset_support = inp->local_strreset_support;
 	asoc->def_send = inp->def_send;
-	asoc->delayed_ack = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
+	asoc->delayed_ack = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
 	asoc->sack_freq = inp->sctp_ep.sctp_sack_freq;
 	asoc->pr_sctp_cnt = 0;
 	asoc->total_output_queue_size = 0;
@@ -2110,9 +2184,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, s
 		}
 		tmr = &net->rxt_timer;
 		if (net->RTO == 0) {
-			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
+			to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
 		} else {
-			to_ticks = MSEC_TO_TICKS(net->RTO);
+			to_ticks = sctp_msecs_to_ticks(net->RTO);
 		}
 		break;
 	case SCTP_TIMER_TYPE_INIT:
@@ -2130,9 +2204,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, s
 		}
 		tmr = &net->rxt_timer;
 		if (net->RTO == 0) {
-			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
+			to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
 		} else {
-			to_ticks = MSEC_TO_TICKS(net->RTO);
+			to_ticks = sctp_msecs_to_ticks(net->RTO);
 		}
 		break;
 	case SCTP_TIMER_TYPE_RECV:
@@ -2149,7 +2223,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, s
 #endif
 		}
 		tmr = &stcb->asoc.dack_timer;
-		to_ticks = MSEC_TO_TICKS(stcb->asoc.delayed_ack);
+		to_ticks = sctp_msecs_to_ticks(stcb->asoc.delayed_ack);
 		break;
 	case SCTP_TIMER_TYPE_SHUTDOWN:
 		/* Here we use the RTO of the destination. */
@@ -2163,9 +2237,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, s
 		}
 		tmr = &net->rxt_timer;
 		if (net->RTO == 0) {
-			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
+			to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
 		} else {
-			to_ticks = MSEC_TO_TICKS(net->RTO);
+			to_ticks = sctp_msecs_to_ticks(net->RTO);
 		}
 		break;
 	case SCTP_TIMER_TYPE_HEARTBEAT:
@@ -2210,7 +2284,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, s
 		 * Now we must convert the to_ticks that are now in ms to
 		 * ticks.
 		 */
-		to_ticks = MSEC_TO_TICKS(to_ticks);
+		to_ticks = sctp_msecs_to_ticks(to_ticks);
 		break;
 	case SCTP_TIMER_TYPE_COOKIE:
 		/*
@@ -2228,9 +2302,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, s
 		}
 		tmr = &net->rxt_timer;
 		if (net->RTO == 0) {
-			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
+			to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
 		} else {
-			to_ticks = MSEC_TO_TICKS(net->RTO);
+			to_ticks = sctp_msecs_to_ticks(net->RTO);
 		}
 		break;
 	case SCTP_TIMER_TYPE_NEWCOOKIE:
@@ -2283,9 +2357,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, s
 		}
 		tmr = &net->rxt_timer;
 		if (net->RTO == 0) {
-			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
+			to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
 		} else {
-			to_ticks = MSEC_TO_TICKS(net->RTO);
+			to_ticks = sctp_msecs_to_ticks(net->RTO);
 		}
 		break;
 	case SCTP_TIMER_TYPE_ASCONF:
@@ -2303,9 +2377,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, s
 		}
 		tmr = &stcb->asoc.asconf_timer;
 		if (net->RTO == 0) {
-			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
+			to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
 		} else {
-			to_ticks = MSEC_TO_TICKS(net->RTO);
+			to_ticks = sctp_msecs_to_ticks(net->RTO);
 		}
 		break;
 	case SCTP_TIMER_TYPE_SHUTDOWNGUARD:
@@ -2323,7 +2397,11 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, s
 		}
 		tmr = &stcb->asoc.shut_guard_timer;
 		if (inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] == 0) {
-			to_ticks = 5 * MSEC_TO_TICKS(stcb->asoc.maxrto);
+			if (stcb->asoc.maxrto < UINT32_MAX / 5) {
+				to_ticks = sctp_msecs_to_ticks(5 * stcb->asoc.maxrto);
+			} else {
+				to_ticks = sctp_msecs_to_ticks(UINT32_MAX);
+			}
 		} else {
 			to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN];
 		}
@@ -2355,9 +2433,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, s
 		}
 		tmr = &stcb->asoc.strreset_timer;
 		if (net->RTO == 0) {
-			to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
+			to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
 		} else {
-			to_ticks = MSEC_TO_TICKS(net->RTO);
+			to_ticks = sctp_msecs_to_ticks(net->RTO);
 		}
 		break;
 	case SCTP_TIMER_TYPE_INPKILL:
@@ -2375,7 +2453,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, s
 #endif
 		}
 		tmr = &inp->sctp_ep.signature_change;
-		to_ticks = MSEC_TO_TICKS(SCTP_INP_KILL_TIMEOUT);
+		to_ticks = sctp_msecs_to_ticks(SCTP_INP_KILL_TIMEOUT);
 		break;
 	case SCTP_TIMER_TYPE_ASOCKILL:
 		if ((inp == NULL) || (stcb == NULL) || (net != NULL)) {
@@ -2387,7 +2465,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, s
 #endif
 		}
 		tmr = &stcb->asoc.strreset_timer;
-		to_ticks = MSEC_TO_TICKS(SCTP_ASOC_KILL_TIMEOUT);
+		to_ticks = sctp_msecs_to_ticks(SCTP_ASOC_KILL_TIMEOUT);
 		break;
 	case SCTP_TIMER_TYPE_ADDR_WQ:
 		if ((inp != NULL) || (stcb != NULL) || (net != NULL)) {
@@ -2412,7 +2490,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, s
 #endif
 		}
 		tmr = &stcb->asoc.delete_prim_timer;
-		to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
+		to_ticks = sctp_msecs_to_ticks(stcb->asoc.initial_rto);
 		break;
 	default:
 #ifdef INVARIANTS

Modified: stable/12/sys/netinet/sctputil.h
==============================================================================
--- stable/12/sys/netinet/sctputil.h	Sun Aug 23 22:24:46 2020	(r364573)
+++ stable/12/sys/netinet/sctputil.h	Sun Aug 23 22:26:38 2020	(r364574)
@@ -392,5 +392,10 @@ void sctp_hc_set_mtu(union sctp_sockstore *, uint16_t,
 uint32_t sctp_hc_get_mtu(union sctp_sockstore *, uint16_t);
 void sctp_set_state(struct sctp_tcb *, int);
 void sctp_add_substate(struct sctp_tcb *, int);
+uint32_t sctp_ticks_to_msecs(uint32_t);
+uint32_t sctp_msecs_to_ticks(uint32_t);
+uint32_t sctp_ticks_to_secs(uint32_t);
+uint32_t sctp_secs_to_ticks(uint32_t);
+
 #endif				/* _KERNEL */
 #endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202008232226.07NMQcFf099160>