Skip to contentSkip to conversation

ipv6: fix possible infinite loop in rt6_fill_node()

PATCH Applied Jiayuan Chen 3 participants 6 messages May 27 – May 29

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/2 ipv6: fix possible infinite loop in rt6_fill_node()

Sashiko reported this issue [1]. Apply the same fix as
commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").

Writers holding tb6_lock can list_del_rcu(&rt->fib6_siblings) without waiting for RCU readers; rt->fib6_siblings.next then still points into the old ring and this softirq-side walker never reaches &rt->fib6_siblings, causing a CPU stall. fib6_purge_rt() always WRITE_ONCE()s rt->fib6_nsiblings to 0 before list_del_rcu(), so an inside-loop check is a reliable detach signal.

[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev

Fixes d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")
---
 net/ipv6/route.c | 2 ++
 1 file changed, 2 insertions(+)
net/ipv6/route.c +2 -0
index b106e5fef9cb..dad416fdc585 100644
@@ -5902,6 +5902,8 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
 
 				goto nla_put_failure;
 			}
+			if (!READ_ONCE(rt->fib6_nsiblings))
+				break;
 		}
 
 		rcu_read_unlock();
Signature · 1 line
2.43.0
#1 lore raw

PATCH 2/2 ipv6: fix possible infinite loop in fib6_select_path()

Found while auditing the same pattern Sashiko reported in rt6_fill_node() [1]. Apply the same fix as
commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").

Writers holding tb6_lock can list_del_rcu(&first->fib6_siblings) without waiting for RCU readers; first->fib6_siblings.next then still points into the old ring and this softirq-side walker never reaches &first->fib6_siblings as its terminator. fib6_purge_rt() always WRITE_ONCE()s first->fib6_nsiblings to 0 before list_del_rcu(), so an inside-loop check is a reliable detach signal.

[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev

Fixes d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")
---
 net/ipv6/route.c | 3 +++
 1 file changed, 3 insertions(+)
net/ipv6/route.c +3 -0
index dad416fdc585..636f0120d7e3 100644
@@ -481,6 +481,9 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
 		const struct fib6_nh *nh = sibling->fib6_nh;
 		int nh_upper_bound;
 
+		if (!READ_ONCE(first->fib6_nsiblings))
+			break;
+
 		nh_upper_bound = atomic_read(&nh->fib_nh_upper_bound);
 		if (hash > nh_upper_bound)
 			continue;
Signature · 1 line
2.43.0
maintainer Reviewed-by on v1 2/2
#2 lore raw

Re: [PATCH net 2/2] ipv6: fix possible infinite loop in fib6_select_path()

Quoted 11 lines · Jiayuan Chen

Found while auditing the same pattern Sashiko reported in rt6_fill_node() [1]. Apply the same fix as
commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").

Writers holding tb6_lock can list_del_rcu(&first->fib6_siblings) without waiting for RCU readers; first->fib6_siblings.next then still points into the old ring and this softirq-side walker never reaches &first->fib6_siblings as its terminator. fib6_purge_rt() always WRITE_ONCE()s first->fib6_nsiblings to 0 before list_del_rcu(), so an inside-loop check is a reliable detach signal.

Quoted 4 lines

[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev

Fixes d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")
maintainer Reviewed-by on v1 1/2
#3 lore raw
In reply to Jiayuan Chen
Quoted 7 lines · Jiayuan Chen

Sashiko reported this issue [1]. Apply the same fix as
commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").

Writers holding tb6_lock can list_del_rcu(&rt->fib6_siblings) without waiting for RCU readers; rt->fib6_siblings.next then still points into the old ring and this softirq-side walker never reaches &rt->fib6_siblings, causing a CPU stall. fib6_purge_rt() always

s/fib6_purge_rt/fib6_del_route/ ?

Quoted 7 lines

WRITE_ONCE()s rt->fib6_nsiblings to 0 before list_del_rcu(), so an inside-loop check is a reliable detach signal.

[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev

Fixes d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")

Sashiko points out two pre-existing issues:

1. Same issue in nft_fib6_info_nh_uses_dev(). Fixed by:
https://lore.kernel.org/all/[email protected]/

2. Missing nlmsg_{end, cancel}() following ip6mr_get_route(). Seems valid, but completely unrelated.

#4 lore raw
Quoted 9 lines · Ido Schimmel
Quoted 7 lines · Jiayuan Chen

Sashiko reported this issue [1]. Apply the same fix as
commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").

Writers holding tb6_lock can list_del_rcu(&rt->fib6_siblings) without waiting for RCU readers; rt->fib6_siblings.next then still points into the old ring and this softirq-side walker never reaches &rt->fib6_siblings, causing a CPU stall. fib6_purge_rt() always

s/fib6_purge_rt/fib6_del_route/ ?

You're right, that's fib6_del_route().

Quoted 16 lines
Quoted 7 lines

WRITE_ONCE()s rt->fib6_nsiblings to 0 before list_del_rcu(), so an inside-loop check is a reliable detach signal.

[1] https://sashiko.dev/#/patchset/20260526020227.4857-1-jiayuan.chen%40linux.dev

Fixes d9ccb18f83ea ("ipv6: Fix soft lockups in fib6_select_path under high next hop churn")

Sashiko points out two pre-existing issues:

1. Same issue in nft_fib6_info_nh_uses_dev(). Fixed by:
https://lore.kernel.org/all/[email protected]/

2. Missing nlmsg_{end, cancel}() following ip6mr_get_route(). Seems valid, but completely unrelated.

#5 lore raw
In reply to Jiayuan Chen
This series was applied to netdev/net.git (main) by Jakub Kicinski <[email protected]>:

Hello:

This series was applied to netdev/net.git (main)
by Jakub Kicinski <[email protected]>:

Quoted 11 lines · On Wed, 27 May 2026 13:31:30 +0800 you wrote:

Sashiko reported this issue [1]. Apply the same fix as
commit f8d8ce1b515a ("ipv6: fix possible infinite loop in fib6_info_uses_dev()").

Writers holding tb6_lock can list_del_rcu(&rt->fib6_siblings) without waiting for RCU readers; rt->fib6_siblings.next then still points into the old ring and this softirq-side walker never reaches &rt->fib6_siblings, causing a CPU stall. fib6_purge_rt() always WRITE_ONCE()s rt->fib6_nsiblings to 0 before list_del_rcu(), so an inside-loop check is a reliable detach signal.

[...]

Here is the summary with links:
- [net,1/2] ipv6: fix possible infinite loop in rt6_fill_node()

    https://git.kernel.org/netdev/net/c/9f72412bcf60
  - [net,2/2] ipv6: fix possible infinite loop in fib6_select_path()
    https://git.kernel.org/netdev/net/c/9c7da87c2dc8

You are awesome, thank you!

Signature · 2 lines
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html