git: 528d5d75e955 - stable/13 - Address issue pointed out in CVE-2020-25705

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Thu, 07 Apr 2022 13:14:33 UTC
The branch stable/13 has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=528d5d75e9557ee8e9fbfee68d15d4e1045cef3d

commit 528d5d75e9557ee8e9fbfee68d15d4e1045cef3d
Author:     George V. Neville-Neil <gnn@FreeBSD.org>
AuthorDate: 2022-03-19 16:48:16 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2022-04-07 07:35:36 +0000

    Address issue pointed out in CVE-2020-25705
    
    Add jitter to the ICMP bandwidth limit to deny a side-channel port scan.
    
    Reviewed by:    kp, philip, cy, emaste
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D27354
    
    (cherry picked from commit ca4cd20c4afeb68ae30c4cc1103280590a099fe7)
---
 sys/netinet/ip_icmp.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index f8dfc21df8f3..505e9a90300e 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -89,6 +89,14 @@ SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim, CTLFLAG_VNET | CTLFLAG_RW,
 	&VNET_NAME(icmplim), 0,
 	"Maximum number of ICMP responses per second");
 
+VNET_DEFINE_STATIC(int, icmplim_curr_jitter) = 0;
+#define V_icmplim_curr_jitter		VNET(icmplim_curr_jitter)
+VNET_DEFINE_STATIC(int, icmplim_jitter) = 16;
+#define	V_icmplim_jitter		VNET(icmplim_jitter)
+SYSCTL_INT(_net_inet_icmp, OID_AUTO, icmplim_jitter, CTLFLAG_VNET | CTLFLAG_RW,
+	&VNET_NAME(icmplim_jitter), 0,
+	"Random icmplim jitter adjustment limit");
+
 VNET_DEFINE_STATIC(int, icmplim_output) = 1;
 #define	V_icmplim_output		VNET(icmplim_output)
 SYSCTL_INT(_net_inet_icmp, OID_AUTO, icmplim_output, CTLFLAG_VNET | CTLFLAG_RW,
@@ -1127,11 +1135,29 @@ badport_bandlim(int which)
 	KASSERT(which >= 0 && which < BANDLIM_MAX,
 	    ("%s: which %d", __func__, which));
 
-	pps = counter_ratecheck(&V_icmp_rates[which].cr, V_icmplim);
+	if ((V_icmplim + V_icmplim_curr_jitter) <= 0)
+		V_icmplim_curr_jitter = -V_icmplim + 1;
+
+	pps = counter_ratecheck(&V_icmp_rates[which].cr, V_icmplim +
+	    V_icmplim_curr_jitter);
+	if (pps > 0) {
+		/*
+		 * Adjust limit +/- to jitter the measurement to deny a
+		 * side-channel port scan as in CVE-2020-25705
+		 */
+		if (V_icmplim_jitter > 0) {
+			int32_t inc =
+			    arc4random_uniform(V_icmplim_jitter * 2 +1)
+			    - V_icmplim_jitter;
+
+			V_icmplim_curr_jitter = inc;
+		}
+	}
 	if (pps == -1)
 		return (-1);
 	if (pps > 0 && V_icmplim_output)
 		log(LOG_NOTICE, "Limiting %s from %jd to %d packets/sec\n",
-			V_icmp_rates[which].descr, (intmax_t )pps, V_icmplim);
+		    V_icmp_rates[which].descr, (intmax_t )pps, V_icmplim +
+		    V_icmplim_curr_jitter);
 	return (0);
 }