Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ipv6: snmp: do not track per idev ICMP6_MIB_RATELIMITHOST

Blamed commit added a critical false sharing on a single
atomic_long_t under DOS, like receiving UDP packets
to closed ports.

Per netns ICMP6_MIB_RATELIMITHOST tracking uses per-cpu
storage and is enough, we do not need per-device and slow tracking.

Fixes: d0941130c9351 ("icmp: Add counters for rate limits")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Jamie Bainbridge <jamie.bainbridge@gmail.com>
Cc: Abhishek Rawal <rawal.abhishek92@gmail.com>
Link: https://patch.msgid.link/20250905165813.1470708-4-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
2fab94bc ceac1fb2

+6 -3
+1 -2
net/ipv6/icmp.c
··· 230 230 } 231 231 rcu_read_unlock(); 232 232 if (!res) 233 - __ICMP6_INC_STATS(net, ip6_dst_idev(dst), 234 - ICMP6_MIB_RATELIMITHOST); 233 + __ICMP6_INC_STATS(net, NULL, ICMP6_MIB_RATELIMITHOST); 235 234 else 236 235 icmp_global_consume(net); 237 236 dst_release(dst);
+5 -1
net/ipv6/proc.c
··· 94 94 SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS), 95 95 SNMP_MIB_ITEM("Icmp6OutErrors", ICMP6_MIB_OUTERRORS), 96 96 SNMP_MIB_ITEM("Icmp6InCsumErrors", ICMP6_MIB_CSUMERRORS), 97 + /* ICMP6_MIB_RATELIMITHOST needs to be last, see snmp6_dev_seq_show(). */ 97 98 SNMP_MIB_ITEM("Icmp6OutRateLimitHost", ICMP6_MIB_RATELIMITHOST), 98 99 }; 99 100 ··· 243 242 snmp6_ipstats_list, 244 243 ARRAY_SIZE(snmp6_ipstats_list), 245 244 offsetof(struct ipstats_mib, syncp)); 245 + 246 + /* Per idev icmp stats do not have ICMP6_MIB_RATELIMITHOST */ 246 247 snmp6_seq_show_item(seq, NULL, idev->stats.icmpv6dev->mibs, 247 - snmp6_icmp6_list, ARRAY_SIZE(snmp6_icmp6_list)); 248 + snmp6_icmp6_list, ARRAY_SIZE(snmp6_icmp6_list) - 1); 249 + 248 250 snmp6_seq_show_icmpv6msg(seq, idev->stats.icmpv6msgdev->mibs); 249 251 return 0; 250 252 }