mbox series

[v2,net-next,0/3] icmp: avoid possible side-channels attacks

Message ID 20240829144641.3880376-1-edumazet@google.com (mailing list archive)
Headers show
Series icmp: avoid possible side-channels attacks | expand

Message

Eric Dumazet Aug. 29, 2024, 2:46 p.m. UTC
Keyu Man reminded us that linux ICMP rate limiting was still allowing
side-channels attacks.

Quoting the fine document [1]:

4.4 Private Source Port Scan Method
...
 We can then use the same global ICMP rate limit as a side
 channel to infer if such an ICMP message has been triggered. At
 first glance, this method can work but at a low speed of one port
 per second, due to the per-IP rate limit on ICMP messages.
 Surprisingly, after we analyze the source code of the ICMP rate
 limit implementation, we find that the global rate limit is checked
 prior to the per-IP rate limit. This means that even if the per-IP
 rate limit may eventually determine that no ICMP reply should be
 sent, a packet is still subjected to the global rate limit check and one
 token is deducted. Ironically, such a decision is consciously made
 by Linux developers to avoid invoking the expensive check of the
 per-IP rate limit [ 22], involving a search process to locate the per-IP
 data structure.
 This effectively means that the per-IP rate limit can be disre-
 garded for the purpose of our side channel based scan, as it only
 determines if the final ICMP reply is generated but has nothing to
 do with the global rate limit counter decrement. As a result, we can
 continue to use roughly the same scan method as efficient as before,
 achieving 1,000 ports per second
...

This series :

1) Changes the order of the two rate limiters to fix the issue.

2-3) Make the 'host-wide' rate limiter a per-netns one.

[1]
Link: https://dl.acm.org/doi/pdf/10.1145/3372297.3417280

v2: added kerneldoc changes for icmp_global_allow() (Simon)

Eric Dumazet (3):
  icmp: change the order of rate limits
  icmp: move icmp_global.credit and icmp_global.stamp to per netns
    storage
  icmp: icmp_msgs_per_sec and icmp_msgs_burst sysctls become per netns

 include/net/ip.h           |   5 +-
 include/net/netns/ipv4.h   |   5 +-
 net/ipv4/icmp.c            | 112 +++++++++++++++++++------------------
 net/ipv4/sysctl_net_ipv4.c |  32 +++++------
 net/ipv6/icmp.c            |  28 ++++++----
 5 files changed, 98 insertions(+), 84 deletions(-)

Comments

Simon Horman Aug. 29, 2024, 8:11 p.m. UTC | #1
On Thu, Aug 29, 2024 at 02:46:38PM +0000, Eric Dumazet wrote:
> Keyu Man reminded us that linux ICMP rate limiting was still allowing
> side-channels attacks.
> 
> Quoting the fine document [1]:
> 
> 4.4 Private Source Port Scan Method
> ...
>  We can then use the same global ICMP rate limit as a side
>  channel to infer if such an ICMP message has been triggered. At
>  first glance, this method can work but at a low speed of one port
>  per second, due to the per-IP rate limit on ICMP messages.
>  Surprisingly, after we analyze the source code of the ICMP rate
>  limit implementation, we find that the global rate limit is checked
>  prior to the per-IP rate limit. This means that even if the per-IP
>  rate limit may eventually determine that no ICMP reply should be
>  sent, a packet is still subjected to the global rate limit check and one
>  token is deducted. Ironically, such a decision is consciously made
>  by Linux developers to avoid invoking the expensive check of the
>  per-IP rate limit [ 22], involving a search process to locate the per-IP
>  data structure.
>  This effectively means that the per-IP rate limit can be disre-
>  garded for the purpose of our side channel based scan, as it only
>  determines if the final ICMP reply is generated but has nothing to
>  do with the global rate limit counter decrement. As a result, we can
>  continue to use roughly the same scan method as efficient as before,
>  achieving 1,000 ports per second
> ...
> 
> This series :
> 
> 1) Changes the order of the two rate limiters to fix the issue.
> 
> 2-3) Make the 'host-wide' rate limiter a per-netns one.
> 
> [1]
> Link: https://dl.acm.org/doi/pdf/10.1145/3372297.3417280
> 
> v2: added kerneldoc changes for icmp_global_allow() (Simon)

Thanks for the update; confirming that part looks good to me.
patchwork-bot+netdevbpf@kernel.org Aug. 30, 2024, 6:40 p.m. UTC | #2
Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Thu, 29 Aug 2024 14:46:38 +0000 you wrote:
> Keyu Man reminded us that linux ICMP rate limiting was still allowing
> side-channels attacks.
> 
> Quoting the fine document [1]:
> 
> 4.4 Private Source Port Scan Method
> ...
>  We can then use the same global ICMP rate limit as a side
>  channel to infer if such an ICMP message has been triggered. At
>  first glance, this method can work but at a low speed of one port
>  per second, due to the per-IP rate limit on ICMP messages.
>  Surprisingly, after we analyze the source code of the ICMP rate
>  limit implementation, we find that the global rate limit is checked
>  prior to the per-IP rate limit. This means that even if the per-IP
>  rate limit may eventually determine that no ICMP reply should be
>  sent, a packet is still subjected to the global rate limit check and one
>  token is deducted. Ironically, such a decision is consciously made
>  by Linux developers to avoid invoking the expensive check of the
>  per-IP rate limit [ 22], involving a search process to locate the per-IP
>  data structure.
>  This effectively means that the per-IP rate limit can be disre-
>  garded for the purpose of our side channel based scan, as it only
>  determines if the final ICMP reply is generated but has nothing to
>  do with the global rate limit counter decrement. As a result, we can
>  continue to use roughly the same scan method as efficient as before,
>  achieving 1,000 ports per second
> ...
> 
> [...]

Here is the summary with links:
  - [v2,net-next,1/3] icmp: change the order of rate limits
    https://git.kernel.org/netdev/net-next/c/8c2bd38b95f7
  - [v2,net-next,2/3] icmp: move icmp_global.credit and icmp_global.stamp to per netns storage
    https://git.kernel.org/netdev/net-next/c/b056b4cd9178
  - [v2,net-next,3/3] icmp: icmp_msgs_per_sec and icmp_msgs_burst sysctls become per netns
    https://git.kernel.org/netdev/net-next/c/f17bf505ff89

You are awesome, thank you!