From 781b5470ec38d0b44991a9f4624fc5ffe91ee5b0 Mon Sep 17 00:00:00 2001 From: Jonah Palmer Date: Thu, 21 Aug 2025 14:26:41 +0000 Subject: [PATCH] net/hub: make net_hub_port_cleanup idempotent Makes the net_hub_port_cleanup function idempotent to avoid double removals by guarding its QLIST_REMOVE with a flag. When using a Xen networking device with hubport backends, e.g.: -accel kvm,xen-version=0x40011 -netdev hubport,... -device xen-net-device,... the shutdown order starts with net_cleanup, which walks the list and deletes netdevs (including hubports). Then Xen's xen_device_unrealize is called, which eventually leads to a second net_hub_port_cleanup call, resulting in a segfault. Fixes: e7891c57 ("net: move backend cleanup to NIC cleanup") Reported-by: David Woodhouse Signed-off-by: Jonah Palmer Signed-off-by: Jason Wang --- net/hub.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/hub.c b/net/hub.c index e3b58b1c4f..ee5881f6d5 100644 --- a/net/hub.c +++ b/net/hub.c @@ -34,6 +34,7 @@ typedef struct NetHubPort { QLIST_ENTRY(NetHubPort) next; NetHub *hub; int id; + bool listed; } NetHubPort; struct NetHub { @@ -129,7 +130,10 @@ static void net_hub_port_cleanup(NetClientState *nc) { NetHubPort *port = DO_UPCAST(NetHubPort, nc, nc); - QLIST_REMOVE(port, next); + if (port->listed) { + QLIST_REMOVE(port, next); + port->listed = false; + } } static NetClientInfo net_hub_port_info = { @@ -159,8 +163,10 @@ static NetHubPort *net_hub_port_new(NetHub *hub, const char *name, port = DO_UPCAST(NetHubPort, nc, nc); port->id = id; port->hub = hub; + port->listed = false; QLIST_INSERT_HEAD(&hub->ports, port, next); + port->listed = true; return port; } -- 2.47.3