FAILED: patch "[PATCH] icmp: change the order of rate limits" failed to apply to 4.19-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 4.19-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-4.19.y
git checkout FETCH_HEAD
git cherry-pick -x 8c2bd38b95f75f3d2a08c93e35303e26d480d24e
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2024100131-unfixed-excursion-b8a2@gregkh' --subject-prefix 'PATCH 4.19.y' HEAD^..
Possible dependencies:
8c2bd38b95f7 ("icmp: change the order of rate limits")d0941130c935 ("icmp: Add counters for rate limits")8032bf1233a7 ("treewide: use get_random_u32_below() instead of deprecated function") c5f0a1728874 ("rhashtable: make test actually random")197173db990c ("treewide: use get_random_bytes() when possible")a251c17aa558 ("treewide: use get_random_u32() when possible")7e3cf0843fe5 ("treewide: use get_random_{u8,u16}() when possible, part 1")8b3ccbc1f1f9 ("treewide: use prandom_u32_max() when possible, part 2")81895a65ec63 ("treewide: use prandom_u32_max() when possible, part 1")27bc50fc9064 ("Merge tag 'mm-stable-2022-10-08' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 8c2bd38b95f75f3d2a08c93e35303e26d480d24e Mon Sep 17 00:00:00 2001
From: Eric Dumazet <[email protected]>
Date: Thu, 29 Aug 2024 14:46:39 +0000
Subject: [PATCH] icmp: change the order of rate limits
ICMP messages are ratelimited :
After the blamed commits, the two rate limiters are applied in this order:
1) host wide ratelimit (icmp_global_allow())
2) Per destination ratelimit (inetpeer based)
In order to avoid side-channels attacks, we need to apply the per destination check first.
This patch makes the following change :
1) icmp_global_allow() checks if the host wide limit is reached. But credits are not yet consumed. This is deferred to 3)
2) The per destination limit is checked/updated.
This might add a new node in inetpeer tree.
3) icmp_global_consume() consumes tokens if prior operations succeeded.
This means that host wide ratelimit is still effective in keeping inetpeer tree small even under DDOS.
As a bonus, I removed icmp_global.lock as the fast path can use a lock-free operation.
include/net/ip.h +2 -0
@@ -795,6 +795,8 @@ static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) }bool icmp_global_allow (void ); +void icmp_global_consume (void ); +extern int sysctl_icmp_msgs_per_sec;extern int sysctl_icmp_msgs_burst;
net/ipv4/icmp.c +56 -47
199 lines not on this page · raw message
net/ipv6/icmp.c +18 -10
@@ -175,14 +175,16 @@ static bool icmpv6_mask_allow(struct net *net, int type)return false; } -static bool icmpv6_global_allow (struct net *net,int type) +static bool icmpv6_global_allow (struct net *net,int type, +bool *apply_ratelimit) {if (icmpv6_mask_allow (net, type))return true; -if (icmp_global_allow ()) +if (icmp_global_allow ()) { + *apply_ratelimit = true;return true; - + }__ICMP_INC_STATS (net,ICMP_MIB_RATELIMITGLOBAL );return false; }
@@ -191,13 +193,13 @@ static bool icmpv6_global_allow(struct net *net, int type)* Check the ICMP output rate limit */ static bool icmpv6_xrlim_allow (struct sock *sk,u8 type, -struct flowi6 *fl6) +struct flowi6 *fl6,bool apply_ratelimit) {struct net *net =sock_net (sk);struct dst_entry *dst;bool res = false; -if (icmpv6_mask_allow (net, type)) +if (!apply_ratelimit)return true;/*
@@ -228,6 +230,8 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,if (!res)__ICMP6_INC_STATS (net,ip6_dst_idev (dst),ICMP6_MIB_RATELIMITHOST ); +else +icmp_global_consume ();dst_release (dst);return res; }
@@ -452,6 +456,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,struct net *net;struct ipv6_pinfo *np;const struct in6_addr *saddr =NULL ; +bool apply_ratelimit = false;struct dst_entry *dst;struct icmp6hdr tmp_hdr;struct flowi6 fl6;
@@ -533,11 +538,12 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,return ; } -/* Needed by both icmp_global_allow and icmpv6_xmit_lock */ +/* Needed by both icmpv6_global_allow and icmpv6_xmit_lock */ local_bh_disable ();/* Check global sysctl_icmp_msgs_per_sec ratelimit */ -if (!(skb->dev->flags &IFF_LOOPBACK ) && !icmpv6_global_allow (net, type)) +if (!(skb->dev->flags &IFF_LOOPBACK ) && + !icmpv6_global_allow (net, type, &apply_ratelimit)) goto out_bh_enable;mip6_addr_swap (skb, parm);
@@ -575,7 +581,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info, np =inet6_sk (sk); -if (!icmpv6_xrlim_allow (sk, type, &fl6)) +if (!icmpv6_xrlim_allow (sk, type, &fl6, apply_ratelimit)) goto out; tmp_hdr.icmp6_type = type;
@@ -717,6 +723,7 @@ static enum skb_drop_reason icmpv6_echo_reply(struct sk_buff *skb)struct ipv6_pinfo *np;const struct in6_addr *saddr =NULL ;struct icmp6hdr *icmph =icmp6_hdr (skb); +bool apply_ratelimit = false;struct icmp6hdr tmp_hdr;struct flowi6 fl6;struct icmpv6_msg msg;
@@ -781,8 +788,9 @@ static enum skb_drop_reason icmpv6_echo_reply(struct sk_buff *skb) goto out;/* Check the ratelimit */ -if ((!(skb->dev->flags &IFF_LOOPBACK ) && !icmpv6_global_allow (net,ICMPV6_ECHO_REPLY )) || - !icmpv6_xrlim_allow (sk,ICMPV6_ECHO_REPLY , &fl6)) +if ((!(skb->dev->flags &IFF_LOOPBACK ) && + !icmpv6_global_allow (net,ICMPV6_ECHO_REPLY , &apply_ratelimit)) || + !icmpv6_xrlim_allow (sk,ICMPV6_ECHO_REPLY , &fl6, apply_ratelimit)) goto out_dst_release; idev =__in6_dev_get (skb->dev);