git: 7668705cb983 - main - tcp/rack: reject wma_divisor values <= 0

From: Maxim Konovalov <maxim_at_FreeBSD.org>
Date: Sat, 17 Oct 2026 18:21:31 UTC
The branch main has been updated by maxim:

URL: https://cgit.FreeBSD.org/src/commit/?id=7668705cb9837d4c3a6db9b3434b3a522220c8ea

commit 7668705cb9837d4c3a6db9b3434b3a522220c8ea
Author:     Maxim Konovalov <maxim@FreeBSD.org>
AuthorDate: 2026-10-16 22:15:00 +0000
Commit:     Maxim Konovalov <maxim@FreeBSD.org>
CommitDate: 2026-10-17 18:19:45 +0000

    tcp/rack: reject wma_divisor values <= 0
    
    The net.inet.tcp.rack.measure.wma_divisor sysctl is the divisor
    of the goodput weighted moving average used when the dynamic
    goodput multiplier is enabled.  Setting it to 0 panics the kernel.
    
    Make the variable and the sysctl unsigned, reject 0 and values
    above INT32_MAX.
    
    MFC after:      1 month
    Found with:     Claude Code Opus 5.5
    Reviewed by:    tuexen, glebius, markj (early version)
    Differential Revision:  https://reviews.freebsd.org/D60759
---
 sys/netinet/tcp_stacks/rack.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c
index fcbe4834b5e4..c1f89a6286b4 100644
--- a/sys/netinet/tcp_stacks/rack.c
+++ b/sys/netinet/tcp_stacks/rack.c
@@ -275,7 +275,7 @@ static int32_t rack_rate_sample_method = USE_RTT_LOW;
 static int32_t rack_pace_every_seg = 0;
 static int32_t rack_delayed_ack_time = 40000;	/* 40ms in usecs */
 static int32_t rack_pacing_delay_reduction = 4;
-static int32_t rack_wma_divisor = 8;		/* For WMA calculation */
+static uint32_t rack_wma_divisor = 8;		/* For WMA calculation */
 static int32_t rack_cwnd_block_ends_measure = 0;
 static int32_t rack_rwnd_block_ends_measure = 0;
 static int32_t rack_def_profile = 0;
@@ -840,6 +840,22 @@ sysctl_rack_clear(SYSCTL_HANDLER_ARGS)
 	return (0);
 }
 
+static int
+sysctl_rack_wma_divisor(SYSCTL_HANDLER_ARGS)
+{
+	uint32_t val;
+	int error;
+
+	val = *(uint32_t *)arg1;
+	error = sysctl_handle_32(oidp, &val, 0, req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+	if (val == 0 || val > INT32_MAX)
+		return (EINVAL);
+	*(uint32_t *)arg1 = val;
+	return (0);
+}
+
 static void
 rack_init_sysctls(void)
 {
@@ -1407,11 +1423,11 @@ rack_init_sysctls(void)
 	    "measure",
 	    CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
 	    "Measure related controls");
-	SYSCTL_ADD_S32(&rack_sysctl_ctx,
+	SYSCTL_ADD_PROC(&rack_sysctl_ctx,
 	    SYSCTL_CHILDREN(rack_measure),
-	    OID_AUTO, "wma_divisor", CTLFLAG_RW,
-	    &rack_wma_divisor, 8,
-	    "When doing b/w calculation what is the  divisor for the WMA");
+	    OID_AUTO, "wma_divisor", CTLTYPE_U32 | CTLFLAG_RW | CTLFLAG_MPSAFE,
+	    &rack_wma_divisor, 0, sysctl_rack_wma_divisor, "IU",
+	    "When doing b/w calculation what is the divisor for the WMA");
 	SYSCTL_ADD_S32(&rack_sysctl_ctx,
 	    SYSCTL_CHILDREN(rack_measure),
 	    OID_AUTO, "end_cwnd", CTLFLAG_RW,