Skip to contentSkip to conversation

ipv4: handle nexthop group shrink races

PATCH Applied Daehyeon Ko 3 participants 7 messages Oct 2 – Oct 6

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

v2 cover ipv4: handle nexthop group shrink races

fib_info_num_path() and fib_info_nhc() can observe different RCU generations of a replaceable nexthop group. An indexed consumer can therefore accept an index from a larger group and receive NULL after a concurrent shrink.

Patch 1 is unchanged from v1. Patch 2 addresses the analogous fib_dump_info_fnhe() race Ido identified. Auditing the remaining accessor pairs found the same issue in the RCU-only hardware-flag notification path, fixed by patch 3. Separate patches retain the correct Fixes tag for each concurrency boundary.

Thanks to Ido for the review and follow-up pointer.

---
v2:
- Carry Ido's Reviewed-by on unchanged patch 1.
- Add separate exception-dump and notification-sizing fixes.

v1: https://lore.kernel.org/netdev/[email protected]/
review: https://lore.kernel.org/netdev/20261001170513.GA1657889@shredder/

Validation:
- Patch 1 retains its deterministic vulnerable/fixed result.
- Patches 2 and 3 are source-audited only. No new allyesconfig or allmodconfig W=1 build or runtime test was run.

Daehyeon Ko (3):
ipv4: stop PMTU walk when nexthop group shrinks
ipv4: stop exception dump when nexthop group shrinks
ipv4: stop route notification sizing when nexthop group shrinks

 net/ipv4/fib_semantics.c | 3 +++
 net/ipv4/route.c         | 5 +++++
 2 files changed, 8 insertions(+)

base-commit: 28bc1ef699610ee09ce3d46a00552f5a0a0144bd

Signature · 1 line
2.55.0
#1 lore raw

PATCH v2 1/3 ipv4: stop PMTU walk when nexthop group shrinks

Commit 7d3f3b4367f3 ("net: ipv4: Cache pmtu for all packet paths if multipath enabled") made __ip_rt_update_pmtu() update every path.

For nexthop objects, fib_info_num_path() and fib_info_nhc() independently load nh->nh_grp. RCU protects each group's lifetime but does not make the loads observe the same group. If replacement shrinks the group after the loop accepts an index, fib_info_nhc() returns NULL and update_or_create_fnhe() dereferences it.

A deterministic probe only widened the existing window between the real operations. On v7.2, an RTM_NEWNEXTHOP replacement published a one-member group after the PMTU reader accepted index 1 from a two-member group, producing:

  KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
  RIP: update_or_create_fnhe+0x45/0x15b0

Stop when the indexed path is absent. Groups are dense, so no later index exists in that snapshot. The same real-writer window completed 114,423 PMTU iterations without an oops with this check. A reproducer is available on request.

Replacement requires CAP_NET_ADMIN in the network namespace. Where unprivileged user namespaces are permitted, a local user can obtain it in a new user and network namespace.

Fixes 7d3f3b4367f3 ("net: ipv4: Cache pmtu for all packet paths if multipath enabled")
Assisted-by LLM
---
 net/ipv4/route.c | 2 ++
 1 file changed, 2 insertions(+)
net/ipv4/route.c +2 -0
index 37674d76f90f0..5f2197874bebc 100644
@@ -1082,6 +1082,8 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
 
 			for (nhsel = 0; nhsel < fib_info_num_path(res.fi); nhsel++) {
 				nhc = fib_info_nhc(res.fi, nhsel);
+				if (!nhc)
+					break;
 				update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock,
 						      jiffies + net->ipv4.ip_rt_mtu_expires);
 			}
Signature · 1 line
2.55.0
#2 lore raw

PATCH v2 2/3 ipv4: stop exception dump when nexthop group shrinks

In reply to Daehyeon Ko

Commit 4ce5dc9316de ("inet: switch inet_dump_fib() to RCU protection") allowed IPv4 FIB dumps to run concurrently with nexthop replacement.

fib_dump_info_fnhe() uses fib_info_num_path() as the loop bound, then fib_info_nhc() independently reloads nh->nh_grp. If RTM_NEWNEXTHOP replaces a group with fewer paths between those loads, fib_info_nhc() returns NULL and the dump dereferences it through nhc_flags.

Stop the walk when the indexed path is absent. Nexthop groups are dense, so the current snapshot has no later path.

Fixes 4ce5dc9316de ("inet: switch inet_dump_fib() to RCU protection")
Assisted-by LLM
---
 net/ipv4/route.c | 3 +++
 1 file changed, 3 insertions(+)
net/ipv4/route.c +3 -0
index 5f2197874bebc..268d8821f7e09 100644
@@ -3170,6 +3170,9 @@ int fib_dump_info_fnhe(struct sk_buff *skb, struct netlink_callback *cb,
 		struct fnhe_hash_bucket *bucket;
 		int err;
 
+		if (!nhc)
+			break;
+
 		if (nhc->nhc_flags & RTNH_F_DEAD)
 			continue;
 
Signature · 1 line
2.55.0
maintainer Reviewed-by on v2 2/3
#3 lore raw

Re: [PATCH net v2 2/3] ipv4: stop exception dump when nexthop group shrinks

Quoted 13 lines · Daehyeon Ko

Commit 4ce5dc9316de ("inet: switch inet_dump_fib() to RCU protection") allowed IPv4 FIB dumps to run concurrently with nexthop replacement.

fib_dump_info_fnhe() uses fib_info_num_path() as the loop bound, then fib_info_nhc() independently reloads nh->nh_grp. If RTM_NEWNEXTHOP replaces a group with fewer paths between those loads, fib_info_nhc() returns NULL and the dump dereferences it through nhc_flags.

Stop the walk when the indexed path is absent. Nexthop groups are dense, so the current snapshot has no later path.

Quoted 6 lines
Fixes 4ce5dc9316de ("inet: switch inet_dump_fib() to RCU protection")
Assisted-by LLM
#4 lore raw

PATCH v2 3/3 ipv4: stop route notification sizing when nexthop group shrinks

In reply to Daehyeon Ko

Commit 680aea08e78c ("net: ipv4: Emit notification when fib hardware flags are changed") added an RCU-only fib_nlmsg_size() call for asynchronous hardware flag notifications.

fib_nlmsg_size() checks fib_info_num_path() before each iteration, then fib_info_nhc() independently reloads nh->nh_grp. If RTM_NEWNEXTHOP replaces a group with fewer paths between those loads, fib_info_nhc() returns NULL and fib_nexthop_nlmsg_size() dereferences it.

Stop sizing when the indexed path is absent. Nexthop groups are dense, so the current snapshot has no later path.

Fixes 680aea08e78c ("net: ipv4: Emit notification when fib hardware flags are changed")
Assisted-by LLM
---
 net/ipv4/fib_semantics.c | 3 +++
 1 file changed, 3 insertions(+)
net/ipv4/fib_semantics.c +3 -0
index 5c9021ea3a799..47469b7758082 100644
@@ -542,6 +542,9 @@ size_t fib_nlmsg_size(struct fib_info *fi)
 			struct fib_nh_common *nhc = fib_info_nhc(fi, i);
 			size_t nhsize;
 
+			if (!nhc)
+				break;
+
 			nhsize = fib_nexthop_nlmsg_size(nhc, nhs != 1);
 
 			if (nhs != 1)
Signature · 1 line
2.55.0
maintainer Reviewed-by on v2 3/3
#5 lore raw

Re: [PATCH net v2 3/3] ipv4: stop route notification sizing when nexthop group shrinks

Quoted 10 lines · Daehyeon Ko

Commit 680aea08e78c ("net: ipv4: Emit notification when fib hardware flags are changed") added an RCU-only fib_nlmsg_size() call for asynchronous hardware flag notifications.

fib_nlmsg_size() checks fib_info_num_path() before each iteration, then fib_info_nhc() independently reloads nh->nh_grp. If RTM_NEWNEXTHOP replaces a group with fewer paths between those loads, fib_info_nhc() returns NULL and fib_nexthop_nlmsg_size() dereferences it.

Quoted 7 lines

Stop sizing when the indexed path is absent. Nexthop groups are dense, so the current snapshot has no later path.

Fixes 680aea08e78c ("net: ipv4: Emit notification when fib hardware flags are changed")
Assisted-by LLM

A group can also grow between fib_nlmsg_size() and fib_dump_info(), leading to the latter returning -EMSGSIZE and triggering the warning. It requires nexthop_compat_mode being set, which I assume most operators disable nowadays if they are using the nexthop API.

Fix with [1]. If v3 is required, include it as patch #4. Otherwise, wait for this series to be applied before sending the fix (to prevent sashiko from flagging the issues being fixed here).

net/ipv4/fib_trie.c +0 -2
index 6ab95e19b3cf..ef3b1ac08ff9 100644
@@ -1079,8 +1079,6 @@ void fib_alias_hw_flags_set(struct net *net, const struct fib_rt_info *fri)
 
 	err = fib_dump_info(skb, 0, 0, RTM_NEWROUTE, fri, 0);
 	if (err < 0) {
-		/* -EMSGSIZE implies BUG in fib_nlmsg_size() */
-		WARN_ON(err == -EMSGSIZE);
 		kfree_skb(skb);
 		goto errout;
 	}
#6 lore raw
In reply to Daehyeon Ko
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 5 lines · On Fri, 2 Oct 2026 13:50:57 +0900 you wrote:

fib_info_num_path() and fib_info_nhc() can observe different RCU generations of a replaceable nexthop group. An indexed consumer can therefore accept an index from a larger group and receive NULL after a concurrent shrink.

Quoted 7 lines

Patch 1 is unchanged from v1. Patch 2 addresses the analogous fib_dump_info_fnhe() race Ido identified. Auditing the remaining accessor pairs found the same issue in the RCU-only hardware-flag notification path, fixed by patch 3. Separate patches retain the correct Fixes tag for each concurrency boundary.

[...]

Here is the summary with links:
- [net,v2,1/3] ipv4: stop PMTU walk when nexthop group shrinks

    https://git.kernel.org/netdev/net/c/6619e01855e6
  - [net,v2,2/3] ipv4: stop exception dump when nexthop group shrinks
    https://git.kernel.org/netdev/net/c/4f4afc07dcb2
  - [net,v2,3/3] ipv4: stop route notification sizing when nexthop group shrinks
    https://git.kernel.org/netdev/net/c/d3daa33c7af9

You are awesome, thank you!

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