Index: sys/netinet/ip_icmp.c =================================================================== --- sys/netinet/ip_icmp.c +++ sys/netinet/ip_icmp.c @@ -88,6 +88,14 @@ &VNET_NAME(icmplim), 0, "Maximum number of ICMP responses per second"); +VNET_DEFINE_STATIC(int, icmplim_curr_inc) = 0; +#define V_icmplim_curr_inc VNET(icmplim_curr_inc) +VNET_DEFINE_STATIC(int, icmplim_inc) = 16; +#define V_icmplim_inc VNET(icmplim_inc) +SYSCTL_INT(_net_inet_icmp, OID_AUTO, 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, @@ -1122,11 +1130,26 @@ KASSERT(which >= 0 && which < BANDLIM_MAX, ("%s: which %d", __func__, which)); - pps = counter_ratecheck(&V_icmp_rates[which].cr, V_icmplim); + pps = counter_ratecheck(&V_icmp_rates[which].cr, V_icmplim + V_icmplim_curr_inc); + if (pps > 0) { + /* + * Adjust limit +/- to jitter the measurement to deny a + * side-channel port scan as in CVE-2020-25705 + */ + if (V_icmplim_inc > 0) { + int32_t inc = arc4random_uniform(V_icmplim_inc * 2 +1) + - V_icmplim_inc; + + if (V_icmplim + inc <= 0) + inc = -V_icmplim + 1; + + V_icmplim_curr_inc = 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_inc); return (0); }