Index: sys/kern/subr_counter.c =================================================================== --- sys/kern/subr_counter.c +++ sys/kern/subr_counter.c @@ -127,7 +127,7 @@ * is number of events since last reset. */ int64_t -counter_ratecheck(struct counter_rate *cr, int64_t limit) +counter_ratecheck(struct counter_rate *cr, int64_t limit, int64_t inc) { int64_t val; int now; @@ -164,7 +164,7 @@ return (val); } - counter_u64_add(cr->cr_rate, 1); + counter_u64_add(cr->cr_rate, inc); if (cr->cr_over != 0) return (-1); if (counter_u64_fetch(cr->cr_rate) > limit) Index: sys/netinet/ip_icmp.c =================================================================== --- sys/netinet/ip_icmp.c +++ sys/netinet/ip_icmp.c @@ -89,6 +89,12 @@ &VNET_NAME(icmplim), 0, "Maximum number of ICMP responses per second"); +VNET_DEFINE_STATIC(int, icmplim_inc) = 3; +#define V_icmplim_inc VNET(icmplim_inc) +SYSCTL_INT(_net_inet_icmp, ICMPCTL_ICMPLIM, icmplim_inc, CTLFLAG_VNET | CTLFLAG_RW, + &VNET_NAME(icmplim_inc), 0, + "Increment value for randomizing the number of ICMP responses per second"); + 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, @@ -1094,6 +1100,11 @@ }; #define V_icmp_rates VNET(icmp_rates) +/* + * Adjust limit +/- to jitter the measurement for security. + * CVE-2020-25705 + */ + static void icmp_bandlimit_init(void) { @@ -1120,6 +1131,7 @@ badport_bandlim(int which) { int64_t pps; + int32_t inc; if (V_icmplim == 0 || which == BANDLIM_UNLIMITED) return (0); @@ -1127,7 +1139,13 @@ KASSERT(which >= 0 && which < BANDLIM_MAX, ("%s: which %d", __func__, which)); - pps = counter_ratecheck(&V_icmp_rates[which].cr, V_icmplim); + /* + * Add random jitter to the administratively set limit. + */ + inc = arc4random_uniform(V_icmplim_inc); + + pps = counter_ratecheck(&V_icmp_rates[which].cr, V_icmplim, inc); + if (pps == -1) return (-1); if (pps > 0 && V_icmplim_output) Index: sys/sys/counter.h =================================================================== --- sys/sys/counter.h +++ sys/sys/counter.h @@ -72,7 +72,7 @@ int cr_over; /* Over limit since cr_ticks? */ }; -int64_t counter_ratecheck(struct counter_rate *, int64_t); +int64_t counter_ratecheck(struct counter_rate *, int64_t, int64_t); #define COUNTER_U64_SYSINIT(c) \ SYSINIT(c##_counter_sysinit, SI_SUB_COUNTER, \