Skip to content

Commit

Permalink
net: netdevsim: try to close UDP port harness races
Browse files Browse the repository at this point in the history
[ Upstream commit 50bf398 ]

syzbot discovered that we remove the debugfs files after we free
the netdev. Try to clean up the relevant dir while the device
is still around.

Reported-by: syzbot+2e5de9e3ab986b71d2bf@syzkaller.appspotmail.com
Fixes: 424be63 ("netdevsim: add UDP tunnel port offload support")
Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Link: https://patch.msgid.link/20250122224503.762705-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Jakub Kicinski authored and Greg Kroah-Hartman committed Mar 13, 2025
1 parent 0d5bca3 commit d9a7079
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 17 deletions.
1 change: 1 addition & 0 deletions drivers/net/netdevsim/netdevsim.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ struct netdevsim {
u32 sleep;
u32 __ports[2][NSIM_UDP_TUNNEL_N_PORTS];
u32 (*ports)[NSIM_UDP_TUNNEL_N_PORTS];
struct dentry *ddir;
struct debugfs_u32_array dfs_ports[2];
} udp_ports;

Expand Down
23 changes: 14 additions & 9 deletions drivers/net/netdevsim/udp_tunnels.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,11 @@ nsim_udp_tunnels_info_reset_write(struct file *file, const char __user *data,
struct net_device *dev = file->private_data;
struct netdevsim *ns = netdev_priv(dev);

memset(ns->udp_ports.ports, 0, sizeof(ns->udp_ports.__ports));
rtnl_lock();
udp_tunnel_nic_reset_ntf(dev);
if (dev->reg_state == NETREG_REGISTERED) {
memset(ns->udp_ports.ports, 0, sizeof(ns->udp_ports.__ports));
udp_tunnel_nic_reset_ntf(dev);
}
rtnl_unlock();

return count;
Expand Down Expand Up @@ -144,23 +146,23 @@ int nsim_udp_tunnels_info_create(struct nsim_dev *nsim_dev,
else
ns->udp_ports.ports = nsim_dev->udp_ports.__ports;

debugfs_create_u32("udp_ports_inject_error", 0600,
ns->nsim_dev_port->ddir,
ns->udp_ports.ddir = debugfs_create_dir("udp_ports",
ns->nsim_dev_port->ddir);

debugfs_create_u32("inject_error", 0600, ns->udp_ports.ddir,
&ns->udp_ports.inject_error);

ns->udp_ports.dfs_ports[0].array = ns->udp_ports.ports[0];
ns->udp_ports.dfs_ports[0].n_elements = NSIM_UDP_TUNNEL_N_PORTS;
debugfs_create_u32_array("udp_ports_table0", 0400,
ns->nsim_dev_port->ddir,
debugfs_create_u32_array("table0", 0400, ns->udp_ports.ddir,
&ns->udp_ports.dfs_ports[0]);

ns->udp_ports.dfs_ports[1].array = ns->udp_ports.ports[1];
ns->udp_ports.dfs_ports[1].n_elements = NSIM_UDP_TUNNEL_N_PORTS;
debugfs_create_u32_array("udp_ports_table1", 0400,
ns->nsim_dev_port->ddir,
debugfs_create_u32_array("table1", 0400, ns->udp_ports.ddir,
&ns->udp_ports.dfs_ports[1]);

debugfs_create_file("udp_ports_reset", 0200, ns->nsim_dev_port->ddir,
debugfs_create_file("reset", 0200, ns->udp_ports.ddir,
dev, &nsim_udp_tunnels_info_reset_fops);

/* Note: it's not normal to allocate the info struct like this!
Expand Down Expand Up @@ -196,6 +198,9 @@ 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;
}
Expand Down
16 changes: 8 additions & 8 deletions tools/testing/selftests/drivers/net/netdevsim/udp_tunnel_nic.sh
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ function pre_ethtool {
}

function check_table {
local path=$NSIM_DEV_DFS/ports/$port/udp_ports_table$1
local path=$NSIM_DEV_DFS/ports/$port/udp_ports/table$1
local -n expected=$2
local last=$3

Expand Down Expand Up @@ -212,7 +212,7 @@ function check_tables {
}

function print_table {
local path=$NSIM_DEV_DFS/ports/$port/udp_ports_table$1
local path=$NSIM_DEV_DFS/ports/$port/udp_ports/table$1
read -a have < $path

tree $NSIM_DEV_DFS/
Expand Down Expand Up @@ -640,7 +640,7 @@ for port in 0 1; do
NSIM_NETDEV=`get_netdev_name old_netdevs`
ifconfig $NSIM_NETDEV up

echo 110 > $NSIM_DEV_DFS/ports/$port/udp_ports_inject_error
echo 110 > $NSIM_DEV_DFS/ports/$port/udp_ports/inject_error

msg="1 - create VxLANs v6"
exp0=( 0 0 0 0 )
Expand All @@ -662,7 +662,7 @@ for port in 0 1; do
new_geneve gnv0 20000

msg="2 - destroy GENEVE"
echo 2 > $NSIM_DEV_DFS/ports/$port/udp_ports_inject_error
echo 2 > $NSIM_DEV_DFS/ports/$port/udp_ports/inject_error
exp1=( `mke 20000 2` 0 0 0 )
del_dev gnv0

Expand Down Expand Up @@ -763,7 +763,7 @@ for port in 0 1; do
msg="create VxLANs v4"
new_vxlan vxlan0 10000 $NSIM_NETDEV

echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports_reset
echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset
check_tables

msg="NIC device goes down"
Expand All @@ -774,7 +774,7 @@ for port in 0 1; do
fi
check_tables

echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports_reset
echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset
check_tables

msg="NIC device goes up again"
Expand All @@ -788,7 +788,7 @@ for port in 0 1; do
del_dev vxlan0
check_tables

echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports_reset
echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset
check_tables

msg="destroy NIC"
Expand Down Expand Up @@ -895,7 +895,7 @@ msg="vacate VxLAN in overflow table"
exp0=( `mke 10000 1` `mke 10004 1` 0 `mke 10003 1` )
del_dev vxlan2

echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports_reset
echo 1 > $NSIM_DEV_DFS/ports/$port/udp_ports/reset
check_tables

msg="tunnels destroyed 2"
Expand Down

0 comments on commit d9a7079

Please sign in to comment.