mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net] ipv4: stop PMTU walk when nexthop group shrinks
@ 2026-10-01  1:05 Daehyeon Ko
  2026-10-01 17:05 ` Ido Schimmel
  2026-10-04 13:02 ` netdev-bot+sashiko
  0 siblings, 2 replies; 3+ messages in thread
From: Daehyeon Ko @ 2026-10-01  1:05 UTC (permalink / raw)
  To: David Ahern, Ido Schimmel
  Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Vladimir Vdovin, netdev, linux-kernel, Daehyeon Ko

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")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
---
 net/ipv4/route.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 37674d76f90f0..5f2197874bebc 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -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);
 			}

base-commit: 4f1da630d13de0370e2f6361f961f1c8b384af1c
-- 
2.55.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH net] ipv4: stop PMTU walk when nexthop group shrinks
  2026-10-01  1:05 [PATCH net] ipv4: stop PMTU walk when nexthop group shrinks Daehyeon Ko
@ 2026-10-01 17:05 ` Ido Schimmel
  2026-10-04 13:02 ` netdev-bot+sashiko
  1 sibling, 0 replies; 3+ messages in thread
From: Ido Schimmel @ 2026-10-01 17:05 UTC (permalink / raw)
  To: Daehyeon Ko
  Cc: David Ahern, David S . Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Vladimir Vdovin, netdev, linux-kernel

On Thu, Oct 01, 2026 at 10:05:50AM +0900, Daehyeon Ko wrote:
> 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")
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>

Reviewed-by: Ido Schimmel <idosch@nvidia.com>

Please check fib_dump_info_fnhe(). It seems to suffer from the same
problem since commit 4ce5dc9316de ("inet: switch inet_dump_fib() to RCU
protection").

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH net] ipv4: stop PMTU walk when nexthop group shrinks
  2026-10-01  1:05 [PATCH net] ipv4: stop PMTU walk when nexthop group shrinks Daehyeon Ko
  2026-10-01 17:05 ` Ido Schimmel
@ 2026-10-04 13:02 ` netdev-bot+sashiko
  1 sibling, 0 replies; 3+ messages in thread
From: netdev-bot+sashiko @ 2026-10-04 13:02 UTC (permalink / raw)
  To: 4ncienth
  Cc: dsahern, idosch, davem, edumazet, kuba, pabeni, horms, deliran,
	netdev, linux-kernel

Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.

Critical: 0 · High: 1 · Medium: 0 · Low: 0

If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).

- [High] The fix is incomplete.

--

ipv4: stop PMTU walk when nexthop group shrinks

The PMTU walk in __ip_rt_update_pmtu() reads the path count with
fib_info_num_path() and then each path with fib_info_nhc(). For nexthop
objects, these two calls load nh->nh_grp separately, so a group
replacement in between can make fib_info_nhc() return NULL. This patch
adds a NULL check and stops the walk at that point.

> diff --git a/net/ipv4/route.c b/net/ipv4/route.c
> index 37674d76f90f0..5f2197874bebc 100644
> --- a/net/ipv4/route.c
> +++ b/net/ipv4/route.c
> @@ -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;

[Severity: High]
Is this fix complete? fib_dump_info_fnhe(), in the same file, has the
same fib_info_num_path()/fib_info_nhc() loop and does not check nhc for
NULL:

net/ipv4/route.c:fib_dump_info_fnhe() {
    ...
	for (nhsel = 0; nhsel < fib_info_num_path(fi); nhsel++) {
		struct fib_nh_common *nhc = fib_info_nhc(fi, nhsel);
		struct fnhe_hash_bucket *bucket;
		int err;

		if (nhc->nhc_flags & RTNH_F_DEAD)
			continue;
    ...
}

For a route that uses a nexthop object, nexthop_num_path() can see a
two-member group and accept nhsel = 1. A writer can then publish a
smaller group on the same struct nexthop, in either of two ways:

replace_nexthop_grp()
    rcu_assign_pointer(old->nh_grp, newg);

remove_nh_grp_entry()
    rcu_assign_pointer(nhp->nh_grp, newg);

After that, nexthop_fib_nhc() loads the new group, and
nexthop_mpath_select() returns NULL because nhsel >= num_nh. That makes
the nhc->nhc_flags read a NULL pointer dereference.

The reader path holds only RCU:

inet_dump_fib()
  fib_table_dump()
    fn_trie_dump_leaf()
      fib_dump_info_fnhe()

inet_dump_fib() is registered with RTNL_FLAG_DUMP_UNLOCKED and takes only
rcu_read_lock(), so nothing stops the RTNL-held nexthop writers from
running at the same time.

The dump_exceptions filter is set by default for non-strict dumps. For
strict dumps it stays set when RTM_F_CLONED is requested, for example by
ip route show cache. The dump itself needs no privilege. The writer
needs CAP_NET_ADMIN in the netns, which the commit message notes is
reachable through an unprivileged user namespace.

If only this patch goes to stable, the same NULL dereference is still
reachable through the route dump with the same writer. Should the same
guard also go into fib_dump_info_fnhe()? Alternatively, could each walk
take a single snapshot of nh_grp, so the count and the per-index lookup
always use the same group?

>  				update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock,
>  						      jiffies + net->ipv4.ip_rt_mtu_expires);
>  			}

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261001010550.2742297-1-4ncienth%40gmail.com

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-04 13:02 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-01  1:05 [PATCH net] ipv4: stop PMTU walk when nexthop group shrinks Daehyeon Ko
2026-10-01 17:05 ` Ido Schimmel
2026-10-04 13:02 ` netdev-bot+sashiko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®