mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
netdevsim: remove ethtool debugfs files before freeing netdev
The ethtool debugfs files point directly into struct netdevsim, which is
allocated as net_device private data. Their containing port directory is
removed only after nsim_destroy() calls free_netdev().
An open simple-attribute file can consequently dereference the freed
private data before the directory is removed. KASAN observed this in
debugfs_u32_get() during network namespace teardown.
Track and remove the ethtool subtree before free_netdev() on both the
normal and registration-failure paths. debugfs removal drains active
file users before returning.
Fixes: ff1f7c17fb ("netdevsim: add pause frame stats")
Reported-by: syzbot+6c25f4750230faf70be9@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=6c25f4750230faf70be9
Cc: <stable+noautosel@kernel.org> # netdevsim is a test harness, it's never loaded on production systems
Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
Link: https://patch.msgid.link/20260628002804.24214-1-alhouseenyousef@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
9facb861dc
commit
2e996ca81f
|
|
@ -252,6 +252,7 @@ void nsim_ethtool_init(struct netdevsim *ns)
|
|||
ns->ethtool.channels = ns->nsim_bus_dev->num_queues;
|
||||
|
||||
ethtool = debugfs_create_dir("ethtool", ns->nsim_dev_port->ddir);
|
||||
ns->ethtool_ddir = ethtool;
|
||||
|
||||
debugfs_create_u32("get_err", 0600, ethtool, &ns->ethtool.get_err);
|
||||
debugfs_create_u32("set_err", 0600, ethtool, &ns->ethtool.set_err);
|
||||
|
|
@ -272,3 +273,8 @@ void nsim_ethtool_init(struct netdevsim *ns)
|
|||
debugfs_create_u32("tx_max_pending", 0600, dir,
|
||||
&ns->ethtool.ring.tx_max_pending);
|
||||
}
|
||||
|
||||
void nsim_ethtool_fini(struct netdevsim *ns)
|
||||
{
|
||||
debugfs_remove(ns->ethtool_ddir);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1165,6 +1165,7 @@ struct netdevsim *nsim_create(struct nsim_dev *nsim_dev,
|
|||
return ns;
|
||||
|
||||
err_free_netdev:
|
||||
nsim_ethtool_fini(ns);
|
||||
free_netdev(dev);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
|
@ -1178,6 +1179,7 @@ void nsim_destroy(struct netdevsim *ns)
|
|||
debugfs_remove(ns->vlan_dfs);
|
||||
debugfs_remove(ns->qr_dfs);
|
||||
debugfs_remove(ns->pp_dfs);
|
||||
nsim_ethtool_fini(ns);
|
||||
|
||||
if (ns->nb.notifier_call)
|
||||
unregister_netdevice_notifier_dev_net(ns->netdev, &ns->nb,
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ struct netdevsim {
|
|||
struct dentry *pp_dfs;
|
||||
struct dentry *qr_dfs;
|
||||
struct dentry *vlan_dfs;
|
||||
struct dentry *ethtool_ddir;
|
||||
|
||||
struct nsim_ethtool ethtool;
|
||||
struct netdevsim __rcu *peer;
|
||||
|
|
@ -169,6 +170,7 @@ void nsim_destroy(struct netdevsim *ns);
|
|||
bool netdev_is_nsim(struct net_device *dev);
|
||||
|
||||
void nsim_ethtool_init(struct netdevsim *ns);
|
||||
void nsim_ethtool_fini(struct netdevsim *ns);
|
||||
|
||||
void nsim_udp_tunnels_debugfs_create(struct nsim_dev *nsim_dev);
|
||||
int nsim_udp_tunnels_info_create(struct nsim_dev *nsim_dev,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user