* [PATCH net] ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings()
@ 2026-09-04 18:06 Naman Gulati
2026-09-06 11:53 ` Ido Schimmel
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Naman Gulati @ 2026-09-04 18:06 UTC (permalink / raw)
To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: netdev, David Ahern, Ido Schimmel, Simon Horman,
Kuniyuki Iwashima, syzbot+a73e5ee0fd534fed75bd, Naman Gulati
syzbot reported a null-ptr-deref in __ip6_del_rt_siblings() [0].
The stack trace hinted towards a null dereference of rt->fib6_node when
fn->leaf is accessed in __ip6_del_rt_siblings(). With
RTNL_FLAG_DOIT_UNLOCKED set, inet6_rtm_delroute() operations run
concurrently without acquiring the RTNL lock. In ip6_route_del(), the
route lookup happens under rcu_read_lock() without acquiring
table->tb6_lock.
Between ip6_route_del() looking up the route and __ip6_del_rt_siblings()
acquiring table->tb6_lock, another thread can modify the routing table.
For example, when an ECMP route is replaced via RTM_NEWROUTE with
NLM_F_REPLACE, fib6_add_rt2node() unlinks all old siblings and sets
iter->fib6_node = NULL. A reproducer was found that triggers this [1].
Add a check to ensure rt->fib6_node is non-null before accessing it.
[0]
KASAN: null-ptr-deref in range [0x0000000000000020-0x0000000000000027]
RIP: 0010:__ip6_del_rt_siblings+0x31e/0x7c0 net/ipv6/route.c:4056
Call Trace:
<TASK>
ip6_route_del+0x1054/0x1110 net/ipv6/route.c:4232
inet6_rtm_delroute+0x5d7/0x6d0 net/ipv6/route.c:5669
rtnetlink_rcv_msg+0x802/0xc00 net/core/rtnetlink.c:7132
netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2556
netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline]
netlink_unicast+0x7f5/0x990 net/netlink/af_netlink.c:1345
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1900
sock_sendmsg_nosec+0x13a/0x180 net/socket.c:800
__sock_sendmsg net/socket.c:815 [inline]
____sys_sendmsg+0x565/0x870 net/socket.c:2713
___sys_sendmsg+0x2a5/0x360 net/socket.c:2767
__sys_sendmsg net/socket.c:2799 [inline]
__do_sys_sendmsg net/socket.c:2804 [inline]
__se_sys_sendmsg net/socket.c:2802 [inline]
__x64_sys_sendmsg+0x1b7/0x290 net/socket.c:2802
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
[1] https://gist.github.com/NamanGulati/0766a1159b6ca61928faaf87425ff899
Fixes: bd11ff421d36 ("ipv6: Get rid of RTNL for SIOCDELRT and RTM_DELROUTE.")
Reported-by: syzbot+a73e5ee0fd534fed75bd@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6a9b03f9.04649fcc.10325f.0003.GAE@google.com
Signed-off-by: Naman Gulati <namangulati@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
---
net/ipv6/route.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 9658939511e0..08bd68f1b5bb 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -4019,6 +4019,7 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
struct net *net = info->nl_net;
struct sk_buff *skb = NULL;
struct fib6_table *table;
+ struct fib6_node *fn;
int err = -ENOENT;
if (rt == net->ipv6.fib6_null_entry)
@@ -4026,9 +4027,13 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
table = rt->fib6_table;
spin_lock_bh(&table->tb6_lock);
+ fn = rcu_dereference_protected(rt->fib6_node,
+ lockdep_is_held(&table->tb6_lock));
+ if (!fn)
+ goto out_unlock;
+
if (rt->fib6_nsiblings && cfg->fc_delete_all_nh) {
struct fib6_info *sibling, *next_sibling;
- struct fib6_node *fn;
/* prefer to send a single notification with all hops */
skb = nlmsg_new(rt6_nlmsg_size(rt), GFP_ATOMIC);
@@ -4051,8 +4056,6 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
* and emit a replace or delete notification, respectively.
*/
info->skip_notify_kernel = 1;
- fn = rcu_dereference_protected(rt->fib6_node,
- lockdep_is_held(&table->tb6_lock));
if (rcu_access_pointer(fn->leaf) == rt) {
struct fib6_info *last_sibling, *replace_rt;
--
2.55.0.979.g7e5102b832-goog
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net] ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings()
2026-09-04 18:06 [PATCH net] ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings() Naman Gulati
@ 2026-09-06 11:53 ` Ido Schimmel
2026-09-07 11:37 ` Fernando Fernandez Mancera
2026-09-09 0:20 ` patchwork-bot+netdevbpf
2 siblings, 0 replies; 5+ messages in thread
From: Ido Schimmel @ 2026-09-06 11:53 UTC (permalink / raw)
To: Naman Gulati
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, David Ahern, Simon Horman, Kuniyuki Iwashima,
syzbot+a73e5ee0fd534fed75bd
On Fri, Sep 04, 2026 at 06:06:44PM +0000, Naman Gulati wrote:
> syzbot reported a null-ptr-deref in __ip6_del_rt_siblings() [0].
>
> The stack trace hinted towards a null dereference of rt->fib6_node when
> fn->leaf is accessed in __ip6_del_rt_siblings(). With
> RTNL_FLAG_DOIT_UNLOCKED set, inet6_rtm_delroute() operations run
> concurrently without acquiring the RTNL lock. In ip6_route_del(), the
> route lookup happens under rcu_read_lock() without acquiring
> table->tb6_lock.
>
> Between ip6_route_del() looking up the route and __ip6_del_rt_siblings()
> acquiring table->tb6_lock, another thread can modify the routing table.
> For example, when an ECMP route is replaced via RTM_NEWROUTE with
> NLM_F_REPLACE, fib6_add_rt2node() unlinks all old siblings and sets
> iter->fib6_node = NULL. A reproducer was found that triggers this [1].
>
> Add a check to ensure rt->fib6_node is non-null before accessing it.
[...]
> Fixes: bd11ff421d36 ("ipv6: Get rid of RTNL for SIOCDELRT and RTM_DELROUTE.")
> Reported-by: syzbot+a73e5ee0fd534fed75bd@syzkaller.appspotmail.com
> Closes: https://lore.kernel.org/netdev/6a9b03f9.04649fcc.10325f.0003.GAE@google.com
> Signed-off-by: Naman Gulati <namangulati@google.com>
> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Sashiko-gemini flagged a pre-existing and unrelated issue that looks
valid. I will check it.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings()
2026-09-04 18:06 [PATCH net] ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings() Naman Gulati
2026-09-06 11:53 ` Ido Schimmel
@ 2026-09-07 11:37 ` Fernando Fernandez Mancera
2026-09-07 15:42 ` Eric Dumazet
2026-09-09 0:20 ` patchwork-bot+netdevbpf
2 siblings, 1 reply; 5+ messages in thread
From: Fernando Fernandez Mancera @ 2026-09-07 11:37 UTC (permalink / raw)
To: Naman Gulati, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: netdev, David Ahern, Ido Schimmel, Simon Horman,
Kuniyuki Iwashima, syzbot+a73e5ee0fd534fed75bd
On 9/4/26 8:06 PM, Naman Gulati wrote:
> syzbot reported a null-ptr-deref in __ip6_del_rt_siblings() [0].
>
> The stack trace hinted towards a null dereference of rt->fib6_node when
> fn->leaf is accessed in __ip6_del_rt_siblings(). With
> RTNL_FLAG_DOIT_UNLOCKED set, inet6_rtm_delroute() operations run
> concurrently without acquiring the RTNL lock. In ip6_route_del(), the
> route lookup happens under rcu_read_lock() without acquiring
> table->tb6_lock.
>
> Between ip6_route_del() looking up the route and __ip6_del_rt_siblings()
> acquiring table->tb6_lock, another thread can modify the routing table.
> For example, when an ECMP route is replaced via RTM_NEWROUTE with
> NLM_F_REPLACE, fib6_add_rt2node() unlinks all old siblings and sets
> iter->fib6_node = NULL. A reproducer was found that triggers this [1].
>
> Add a check to ensure rt->fib6_node is non-null before accessing it.
>
> [0]
> KASAN: null-ptr-deref in range [0x0000000000000020-0x0000000000000027]
> RIP: 0010:__ip6_del_rt_siblings+0x31e/0x7c0 net/ipv6/route.c:4056
> Call Trace:
> <TASK>
> ip6_route_del+0x1054/0x1110 net/ipv6/route.c:4232
> inet6_rtm_delroute+0x5d7/0x6d0 net/ipv6/route.c:5669
> rtnetlink_rcv_msg+0x802/0xc00 net/core/rtnetlink.c:7132
> netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2556
> netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline]
> netlink_unicast+0x7f5/0x990 net/netlink/af_netlink.c:1345
> netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1900
> sock_sendmsg_nosec+0x13a/0x180 net/socket.c:800
> __sock_sendmsg net/socket.c:815 [inline]
> ____sys_sendmsg+0x565/0x870 net/socket.c:2713
> ___sys_sendmsg+0x2a5/0x360 net/socket.c:2767
> __sys_sendmsg net/socket.c:2799 [inline]
> __do_sys_sendmsg net/socket.c:2804 [inline]
> __se_sys_sendmsg net/socket.c:2802 [inline]
> __x64_sys_sendmsg+0x1b7/0x290 net/socket.c:2802
> do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
> do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
> entry_SYSCALL_64_after_hwframe+0x77/0x7f
> </TASK>
>
> [1] https://gist.github.com/NamanGulati/0766a1159b6ca61928faaf87425ff899
>
> Fixes: bd11ff421d36 ("ipv6: Get rid of RTNL for SIOCDELRT and RTM_DELROUTE.")
> Reported-by: syzbot+a73e5ee0fd534fed75bd@syzkaller.appspotmail.com
> Closes: https://lore.kernel.org/netdev/6a9b03f9.04649fcc.10325f.0003.GAE@google.com
> Signed-off-by: Naman Gulati <namangulati@google.com>
> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
Thanks!
> ---
> net/ipv6/route.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index 9658939511e0..08bd68f1b5bb 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -4019,6 +4019,7 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
> struct net *net = info->nl_net;
> struct sk_buff *skb = NULL;
> struct fib6_table *table;
> + struct fib6_node *fn;
> int err = -ENOENT;
>
> if (rt == net->ipv6.fib6_null_entry)
> @@ -4026,9 +4027,13 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
> table = rt->fib6_table;
> spin_lock_bh(&table->tb6_lock);
>
> + fn = rcu_dereference_protected(rt->fib6_node,
> + lockdep_is_held(&table->tb6_lock));
> + if (!fn)
> + goto out_unlock;
> +
> if (rt->fib6_nsiblings && cfg->fc_delete_all_nh) {
> struct fib6_info *sibling, *next_sibling;
> - struct fib6_node *fn;
>
> /* prefer to send a single notification with all hops */
> skb = nlmsg_new(rt6_nlmsg_size(rt), GFP_ATOMIC);
> @@ -4051,8 +4056,6 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
> * and emit a replace or delete notification, respectively.
> */
> info->skip_notify_kernel = 1;
> - fn = rcu_dereference_protected(rt->fib6_node,
> - lockdep_is_held(&table->tb6_lock));
> if (rcu_access_pointer(fn->leaf) == rt) {
> struct fib6_info *last_sibling, *replace_rt;
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings()
2026-09-07 11:37 ` Fernando Fernandez Mancera
@ 2026-09-07 15:42 ` Eric Dumazet
0 siblings, 0 replies; 5+ messages in thread
From: Eric Dumazet @ 2026-09-07 15:42 UTC (permalink / raw)
To: Fernando Fernandez Mancera
Cc: Naman Gulati, David S . Miller, Jakub Kicinski, Paolo Abeni,
netdev, David Ahern, Ido Schimmel, Simon Horman,
Kuniyuki Iwashima, syzbot+a73e5ee0fd534fed75bd
On Mon, Sep 7, 2026 at 1:38 PM Fernando Fernandez Mancera
<fmancera@suse.de> wrote:
>
> On 9/4/26 8:06 PM, Naman Gulati wrote:
> > syzbot reported a null-ptr-deref in __ip6_del_rt_siblings() [0].
> >
> > The stack trace hinted towards a null dereference of rt->fib6_node when
> > fn->leaf is accessed in __ip6_del_rt_siblings(). With
> > RTNL_FLAG_DOIT_UNLOCKED set, inet6_rtm_delroute() operations run
> > concurrently without acquiring the RTNL lock. In ip6_route_del(), the
> > route lookup happens under rcu_read_lock() without acquiring
> > table->tb6_lock.
> >
> > Between ip6_route_del() looking up the route and __ip6_del_rt_siblings()
> > acquiring table->tb6_lock, another thread can modify the routing table.
> > For example, when an ECMP route is replaced via RTM_NEWROUTE with
> > NLM_F_REPLACE, fib6_add_rt2node() unlinks all old siblings and sets
> > iter->fib6_node = NULL. A reproducer was found that triggers this [1].
> >
> > Add a check to ensure rt->fib6_node is non-null before accessing it.
> >
> > [0]
> > KASAN: null-ptr-deref in range [0x0000000000000020-0x0000000000000027]
> > RIP: 0010:__ip6_del_rt_siblings+0x31e/0x7c0 net/ipv6/route.c:4056
> > Call Trace:
> > <TASK>
> > ip6_route_del+0x1054/0x1110 net/ipv6/route.c:4232
> > inet6_rtm_delroute+0x5d7/0x6d0 net/ipv6/route.c:5669
> > rtnetlink_rcv_msg+0x802/0xc00 net/core/rtnetlink.c:7132
> > netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2556
> > netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline]
> > netlink_unicast+0x7f5/0x990 net/netlink/af_netlink.c:1345
> > netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1900
> > sock_sendmsg_nosec+0x13a/0x180 net/socket.c:800
> > __sock_sendmsg net/socket.c:815 [inline]
> > ____sys_sendmsg+0x565/0x870 net/socket.c:2713
> > ___sys_sendmsg+0x2a5/0x360 net/socket.c:2767
> > __sys_sendmsg net/socket.c:2799 [inline]
> > __do_sys_sendmsg net/socket.c:2804 [inline]
> > __se_sys_sendmsg net/socket.c:2802 [inline]
> > __x64_sys_sendmsg+0x1b7/0x290 net/socket.c:2802
> > do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
> > do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
> > entry_SYSCALL_64_after_hwframe+0x77/0x7f
> > </TASK>
> >
> > [1] https://gist.github.com/NamanGulati/0766a1159b6ca61928faaf87425ff899
> >
> > Fixes: bd11ff421d36 ("ipv6: Get rid of RTNL for SIOCDELRT and RTM_DELROUTE.")
> > Reported-by: syzbot+a73e5ee0fd534fed75bd@syzkaller.appspotmail.com
> > Closes: https://lore.kernel.org/netdev/6a9b03f9.04649fcc.10325f.0003.GAE@google.com
> > Signed-off-by: Naman Gulati <namangulati@google.com>
> > Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
>
> Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Thanks Naman!
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings()
2026-09-04 18:06 [PATCH net] ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings() Naman Gulati
2026-09-06 11:53 ` Ido Schimmel
2026-09-07 11:37 ` Fernando Fernandez Mancera
@ 2026-09-09 0:20 ` patchwork-bot+netdevbpf
2 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-09-09 0:20 UTC (permalink / raw)
To: Naman Gulati
Cc: davem, edumazet, kuba, pabeni, netdev, dsahern, idosch, horms,
kuniyu, syzbot+a73e5ee0fd534fed75bd
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Fri, 4 Sep 2026 18:06:44 +0000 you wrote:
> syzbot reported a null-ptr-deref in __ip6_del_rt_siblings() [0].
>
> The stack trace hinted towards a null dereference of rt->fib6_node when
> fn->leaf is accessed in __ip6_del_rt_siblings(). With
> RTNL_FLAG_DOIT_UNLOCKED set, inet6_rtm_delroute() operations run
> concurrently without acquiring the RTNL lock. In ip6_route_del(), the
> route lookup happens under rcu_read_lock() without acquiring
> table->tb6_lock.
>
> [...]
Here is the summary with links:
- [net] ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings()
https://git.kernel.org/netdev/net/c/cdca92eddc02
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-09 0:21 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-04 18:06 [PATCH net] ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings() Naman Gulati
2026-09-06 11:53 ` Ido Schimmel
2026-09-07 11:37 ` Fernando Fernandez Mancera
2026-09-07 15:42 ` Eric Dumazet
2026-09-09 0:20 ` patchwork-bot+netdevbpf
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.