From 0aa29d57e4fb7a9d8a9593da1e8a27f374052d2f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 15 Oct 2020 11:42:00 -0700 Subject: [PATCH 2468/2944] icmp: randomize the global rate limiter to #31887426 commit b38e7819cae946e2edf869e604af1e65a5d241c5 upstream. Keyu Man reported that the ICMP rate limiter could be used by attackers to get useful signal. Details will be provided in an upcoming academic publication. Our solution is to add some noise, so that the attackers no longer can get help from the predictable token bucket limiter. Fixes: 4cdf507d5452 ("icmp: add a global rate limitation") Signed-off-by: Eric Dumazet Reported-by: Keyu Man Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman Fixes: CVE-2020-25705 Signed-off-by: Shile Zhang Acked-by: Joseph Qi --- Documentation/networking/ip-sysctl.txt | 4 +++- net/ipv4/icmp.c | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 6bada13..e26d94e 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -945,12 +945,14 @@ icmp_ratelimit - INTEGER icmp_msgs_per_sec - INTEGER Limit maximal number of ICMP packets sent per second from this host. Only messages whose type matches icmp_ratemask (see below) are - controlled by this limit. + controlled by this limit. For security reasons, the precise count + of messages per second is randomized. Default: 1000 icmp_msgs_burst - INTEGER icmp_msgs_per_sec controls number of ICMP packets sent per second, while icmp_msgs_burst controls the burst size of these packets. + For security reasons, the precise burst size is randomized. Default: 50 icmp_ratemask - INTEGER diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 0167e23..65f1ddf 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -244,7 +244,7 @@ static inline void icmp_xmit_unlock(struct sock *sk) /** * icmp_global_allow - Are we allowed to send one more ICMP message ? * - * Uses a token bucket to limit our ICMP messages to sysctl_icmp_msgs_per_sec. + * Uses a token bucket to limit our ICMP messages to ~sysctl_icmp_msgs_per_sec. * Returns false if we reached the limit and can not send another packet. * Note: called with BH disabled */ @@ -271,7 +271,10 @@ bool icmp_global_allow(void) } credit = min_t(u32, icmp_global.credit + incr, sysctl_icmp_msgs_burst); if (credit) { - credit--; + /* We want to use a credit of one in average, but need to randomize + * it for security reasons. + */ + credit = max_t(int, credit - prandom_u32_max(3), 0); rc = true; } icmp_global.credit = credit; -- 1.8.3.1