Subject: Re: [PATCH net 1/1] net: l3mdev: Ignore non-L3 uppers in l3mdev_fib_table_rcu

From: Ido Schimmel <[email-masked]>
Date: Mon, 6 Apr 2026 13:33:50 +0300

On Sat, Apr 04, 2026 at 07:52:03PM +0800, Ao Zhou wrote:
> From: Haoze Xie <[email-masked]>
> 
> l3mdev_fib_table_rcu() assumes that any upper device observed for
> an IFF_L3MDEV_SLAVE device is an L3 master and dereferences
> master->l3mdev_ops unconditionally.
> 
> VRF slave setup sets IFF_L3MDEV_SLAVE before the upper link is fully
> switched, so readers can transiently observe a non-L3 upper such as a
> bridge and follow a NULL l3mdev_ops pointer. Require the current upper
> to still be an L3 master before consulting its FIB table.

Do you have a reproducer? I don't see how that can happen.

do_set_master() ensures that the device doesn't have a master when
ndo_add_slave() is called. Meaning, if netif_is_l3_slave() is true and
netdev_master_upper_dev_get_rcu() resolved a master device, it's
guaranteed to be a VRF.

> 
> Fixes: fee6d4c777a1 ("net: Add netif_is_l3_slave")
> Reported-by: Yifan Wu <[email-masked]>
> Reported-by: Juefei Pu <[email-masked]>
> Co-developed-by: Yuan Tan <[email-masked]>
> Signed-off-by: Yuan Tan <[email-masked]>
> Suggested-by: Xin Liu <[email-masked]>
> Signed-off-by: Haoze Xie <[email-masked]>
> Signed-off-by: Ao Zhou <[email-masked]>
> ---
>  net/l3mdev/l3mdev.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/l3mdev/l3mdev.c b/net/l3mdev/l3mdev.c
> index 5432a5f2dfc8..b8a3030cb2c4 100644
> --- a/net/l3mdev/l3mdev.c
> +++ b/net/l3mdev/l3mdev.c
> @@ -177,7 +177,7 @@ u32 l3mdev_fib_table_rcu(const struct net_device *dev)
>  		const struct net_device *master;
> 
>  		master = netdev_master_upper_dev_get_rcu(_dev);
> -		if (master &&
> +		if (master && netif_is_l3_master(master) &&
>  		    master->l3mdev_ops->l3mdev_fib_table)
>  			tb_id = master->l3mdev_ops->l3mdev_fib_table(master);
>  	}
> --
> 2.53.0
>