Commit 0052c6ac authored by Jakub Kicinski's avatar Jakub Kicinski Committed by Wentao Guan
Browse files

net: netdevsim: try to close UDP port harness races

stable inclusion
from stable-v6.6.76
commit b91034314ad24a5dcdd4739035e9f787a9030a9e
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBW08Q

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=b91034314ad24a5dcdd4739035e9f787a9030a9e



--------------------------------

[ Upstream commit 50bf398e1ceacb9a7f85bd3bdca065ebe5cb6159 ]

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: default avatar <syzbot+2e5de9e3ab986b71d2bf@syzkaller.appspotmail.com>
Fixes: 424be63a ("netdevsim: add UDP tunnel port offload support")
Reviewed-by: default avatarMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Link: https://patch.msgid.link/20250122224503.762705-1-kuba@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
(cherry picked from commit b91034314ad24a5dcdd4739035e9f787a9030a9e)
Signed-off-by: default avatarWentao Guan <guanwentao@uniontech.com>
parent a4e35b0c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -121,6 +121,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;

+14 −9
Original line number Diff line number Diff line
@@ -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();
	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;
@@ -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!
@@ -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;
}
+8 −8
Original line number Diff line number Diff line
@@ -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

@@ -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/
@@ -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 )
@@ -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

@@ -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"
@@ -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"
@@ -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"
@@ -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"