Re: [PATCH RFC v2] netdevsim: remove debugfs files before freeing net_device
Aleksandr Nogikh <[email protected]>
| Newsgroups | dev.linux.lists.syzbot |
|---|---|
| Message-ID | <CANp29Y6gq+X76VDzG9vePaX4+R1i=aFCRR6JLK6F3LTvP0L9EQ@mail.gmail.com> |
#syz upstream On Wed, Jun 24, 2026 at 3:04 PM 'syzbot' via syzkaller-upstream-moderation <[email protected]> wrote: > > A KASAN slab-use-after-free was detected in debugfs_u32_get() when reading > a debugfs file associated with a netdevsim port. > > BUG: KASAN: slab-use-after-free in debugfs_u32_get+0x6c/0x70 > Read of size 4 at addr ffff88810cd6db00 > > Call Trace: > debugfs_u32_get+0x6c/0x70 > simple_attr_read+0x227/0x490 > debugfs_attr_read+0x76/0x130 > vfs_read+0x213/0xa80 > > The root cause is that the net_device (and its embedded netdevsim private > data) is freed before its associated debugfs files are removed. When a user > reads a debugfs file like rx_max_pending, debugfs_u32_get() dereferences a > pointer to the freed memory. This happens because nsim_destroy() calls > free_netdev() but does not remove the debugfs files created by > nsim_ethtool_init() or nsim_bpf_init(). These files are only removed later > when nsim_dev_port_debugfs_exit() is called. A similar issue exists in the > error path of nsim_create(). > > To fix this, swap the teardown order in __nsim_dev_port_del() and the > __nsim_dev_port_add() error path so that nsim_dev_port_debugfs_exit() is > called before nsim_destroy(). This ensures the debugfs directory is > recursively removed before the net_device is freed. Additionally, remove > explicit debugfs_remove() calls from various subsystem teardown functions > (like nsim_psp_uninit, nsim_ipsec_teardown, etc.) since the parent > directory is now removed earlier, which would otherwise lead to a > use-after-free of the dentry itself. Finally, ensure the debugfs directory > is removed before free_netdev() is called in the nsim_create() error path. > > Fixes: e05b2d141fef ("netdevsim: move netdev creation/destruction to dev probe") > Assisted-by: Gemini:gemini-3.1-pro-preview Gemini:gemini-3-flash-preview syzbot > Reported-by: [email protected] > Closes: https://syzkaller.appspot.com/bug?extid=6c25f4750230faf70be9 > Link: https://syzkaller.appspot.com/ai_job?id=f0f1a72a-a527-478e-a31c-7b83cdfee8d1 > To: "Andrew Lunn" <[email protected]> > To: "David S. Miller" <[email protected]> > To: "Eric Dumazet" <[email protected]> > To: "Jakub Kicinski" <[email protected]> > To: <[email protected]> > To: "Paolo Abeni" <[email protected]> > Cc: <[email protected]> > > --- > v2: > - Removed unused dentry pointers (pp_dfs, qr_dfs, vlan_dfs) from struct netdevsim. > - Updated nsim_create() to create debugfs files without storing their dentries. > - Added IS_ERR_OR_NULL check for ns in __nsim_dev_port_add() error path. > > v1: > https://lore.kernel.org/all/[email protected]/T/ > --- > diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c > index f00fc2f9e..4c2c9aa1e 100644 > --- a/drivers/net/netdevsim/dev.c > +++ b/drivers/net/netdevsim/dev.c > @@ -1516,17 +1516,17 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_typ > err = devl_rate_leaf_create(&nsim_dev_port->devlink_port, > nsim_dev_port, NULL); > if (err) > - goto err_nsim_destroy; > + goto err_port_debugfs_exit; > } > > list_add(&nsim_dev_port->list, &nsim_dev->port_list); > > return 0; > > -err_nsim_destroy: > - nsim_destroy(nsim_dev_port->ns); > err_port_debugfs_exit: > nsim_dev_port_debugfs_exit(nsim_dev_port); > + if (!IS_ERR_OR_NULL(nsim_dev_port->ns)) > + nsim_destroy(nsim_dev_port->ns); > err_port_resource_unregister: > if (nsim_dev_port_is_pf(nsim_dev_port)) > devl_port_resources_unregister(devlink_port); > @@ -1544,8 +1544,8 @@ static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port) > list_del(&nsim_dev_port->list); > if (nsim_dev_port_is_vf(nsim_dev_port)) > devl_rate_leaf_destroy(&nsim_dev_port->devlink_port); > - nsim_destroy(nsim_dev_port->ns); > nsim_dev_port_debugfs_exit(nsim_dev_port); > + nsim_destroy(nsim_dev_port->ns); > if (nsim_dev_port_is_pf(nsim_dev_port)) > devl_port_resources_unregister(devlink_port); > devl_port_unregister(devlink_port); > diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c > index 36a1be492..0bc9f42a5 100644 > --- a/drivers/net/netdevsim/ipsec.c > +++ b/drivers/net/netdevsim/ipsec.c > @@ -292,5 +292,4 @@ void nsim_ipsec_teardown(struct netdevsim *ns) > if (ipsec->count) > netdev_err(ns->netdev, "tearing down IPsec offload with %d SAs left\n", > ipsec->count); > - debugfs_remove_recursive(ipsec->pfile); > } > diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c > index a75076891..240107369 100644 > --- a/drivers/net/netdevsim/netdev.c > +++ b/drivers/net/netdevsim/netdev.c > @@ -1154,16 +1154,17 @@ struct netdevsim *nsim_create(struct nsim_dev *nsim_dev, > if (err) > goto err_free_netdev; > > - ns->pp_dfs = debugfs_create_file("pp_hold", 0600, nsim_dev_port->ddir, > - ns, &nsim_pp_hold_fops); > - ns->qr_dfs = debugfs_create_file("queue_reset", 0200, > - nsim_dev_port->ddir, ns, > - &nsim_qreset_fops); > - ns->vlan_dfs = debugfs_create_file("vlan", 0400, nsim_dev_port->ddir, > - ns, &nsim_vlan_fops); > + debugfs_create_file("pp_hold", 0600, nsim_dev_port->ddir, ns, > + &nsim_pp_hold_fops); > + debugfs_create_file("queue_reset", 0200, nsim_dev_port->ddir, ns, > + &nsim_qreset_fops); > + debugfs_create_file("vlan", 0400, nsim_dev_port->ddir, ns, > + &nsim_vlan_fops); > return ns; > > err_free_netdev: > + debugfs_remove_recursive(nsim_dev_port->ddir); > + nsim_dev_port->ddir = NULL; > free_netdev(dev); > return ERR_PTR(err); > } > @@ -1174,10 +1175,6 @@ void nsim_destroy(struct netdevsim *ns) > struct netdevsim *peer; > u16 vid; > > - debugfs_remove(ns->vlan_dfs); > - debugfs_remove(ns->qr_dfs); > - debugfs_remove(ns->pp_dfs); > - > if (ns->nb.notifier_call) > unregister_netdevice_notifier_dev_net(ns->netdev, &ns->nb, > &ns->nn); > diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h > index d909c4160..29cbf004a 100644 > --- a/drivers/net/netdevsim/netdevsim.h > +++ b/drivers/net/netdevsim/netdevsim.h > @@ -153,9 +153,6 @@ struct netdevsim { > } udp_ports; > > struct page *page; > - struct dentry *pp_dfs; > - struct dentry *qr_dfs; > - struct dentry *vlan_dfs; > > struct nsim_ethtool ethtool; > struct netdevsim __rcu *peer; > diff --git a/drivers/net/netdevsim/psp.c b/drivers/net/netdevsim/psp.c > index 6936ecb81..2f27a2114 100644 > --- a/drivers/net/netdevsim/psp.c > +++ b/drivers/net/netdevsim/psp.c > @@ -227,7 +227,6 @@ static void __nsim_psp_uninit(struct netdevsim *ns, bool teardown) > > void nsim_psp_uninit(struct netdevsim *ns) > { > - debugfs_remove(ns->psp.rereg); > mutex_destroy(&ns->psp.rereg_lock); > __nsim_psp_uninit(ns, true); > } > diff --git a/drivers/net/netdevsim/udp_tunnels.c b/drivers/net/netdevsim/udp_tunnels.c > index 89fff76e5..a69b15f12 100644 > --- a/drivers/net/netdevsim/udp_tunnels.c > +++ b/drivers/net/netdevsim/udp_tunnels.c > @@ -188,9 +188,6 @@ int nsim_udp_tunnels_info_create(struct nsim_dev *nsim_dev, > > void nsim_udp_tunnels_info_destroy(struct net_device *dev) > { > - struct netdevsim *ns = netdev_priv(dev); > - > - debugfs_remove_recursive(ns->udp_ports.ddir); > kfree(dev->udp_tunnel_nic_info); > dev->udp_tunnel_nic_info = NULL; > } > > > base-commit: 8cd9520d35a6c38db6567e97dd93b1f11f185dc6 > -- > This is an AI-generated patch subject to moderation. > Reply with '#syz upstream' to Sign-off the patch as a human author > and send it to the upstream kernel mailing lists. > Reply with '#syz reject' to reject it ('#syz unreject' to undo). > > See https://goo.gle/syzbot-ai-patches for information about AI-generated patches. > You can comment on the patch as usual, syzbot will try to address > the comments and send a new version of the patch if necessary. > syzbot engineers can be reached at [email protected]. > > -- > You received this message because you are subscribed to the Google Groups "syzkaller-upstream-moderation" group. > To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. > To view this discussion visit https://groups.google.com/d/msgid/syzkaller-upstream-moderation/eda8ccdd-476a-4387-95bf-aeedb3545c69%40mail.kernel.org.