* [PATCH net] netdevsim: tc: serialize access to nsim_block_cb_list
@ 2026-07-19 17:50 Weiming Shi
0 siblings, 0 replies; only message in thread
From: Weiming Shi @ 2026-07-19 17:50 UTC (permalink / raw)
To: Jakub Kicinski, Andrew Lunn, David S . Miller, Eric Dumazet,
Paolo Abeni
Cc: Pablo Neira Ayuso, netdev, linux-kernel, Xiang Mei, Weiming Shi,
stable
nsim_setup_tc() passes a single global nsim_block_cb_list, shared by every
netdevsim device, to flow_block_cb_setup_simple(). That helper does
list_add_tail()/list_del() on the list on block bind/unbind and walks it
in flow_block_cb_is_busy(); it takes no lock of its own and relies on the
caller for serialization.
The tc control path calls ndo_setup_tc(TC_SETUP_BLOCK) under rtnl, but the
nf_tables hardware offload path reaches it under the per-netns nftables
commit_mutex only. Two nft transactions committing offload chains from
different netns thus run flow_block_cb_setup_simple() on the same list
concurrently, corrupting it and freeing a flow_block_cb that the other CPU
still walks:
list_del corruption. prev->next should be ffff88801f18ff00, but was ffff88801de82b00.
kernel BUG at lib/list_debug.c:62!
RIP: 0010:__list_del_entry_valid_or_report (lib/list_debug.c:62)
flow_block_cb_setup_simple (net/core/flow_offload.c:369)
nsim_setup_tc (drivers/net/netdevsim/tc.c)
nft_block_offload_cmd (net/netfilter/nf_tables_offload.c:394)
nft_flow_rule_offload_commit (net/netfilter/nf_tables_offload.c:585)
nf_tables_commit (net/netfilter/nf_tables_api.c:10490)
nfnetlink_rcv_batch (net/netfilter/nfnetlink.c:577)
nfnetlink_rcv (net/netfilter/nfnetlink.c:649)
netlink_unicast (net/netlink/af_netlink.c:1314)
netlink_sendmsg (net/netlink/af_netlink.c:1889)
__sys_sendto (net/socket.c:729)
With KASAN the same race is reported as a slab-use-after-free read of the
freed flow_block_cb (kmalloc-192) in flow_block_cb_setup_simple(). The
trace above is from a 6.12.y reproduction.
Serialize the list with a mutex. ndo_setup_tc(TC_SETUP_BLOCK) always runs
in process context, so sleeping on the mutex is fine.
Fixes: 955bcb6ea0df ("drivers: net: use flow block API")
Reported-by: Xiang Mei <xmei5@asu.edu>
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
drivers/net/netdevsim/tc.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/net/netdevsim/tc.c b/drivers/net/netdevsim/tc.c
index a415e02a6df1..30dd7f924b71 100644
--- a/drivers/net/netdevsim/tc.c
+++ b/drivers/net/netdevsim/tc.c
@@ -72,11 +72,13 @@ static int nsim_setup_tc_ets(struct net_device *dev,
}
static LIST_HEAD(nsim_block_cb_list);
+static DEFINE_MUTEX(nsim_block_cb_lock);
int
nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
{
struct netdevsim *ns = netdev_priv(dev);
+ int err;
switch (type) {
case TC_SETUP_QDISC_TAPRIO:
@@ -84,10 +86,13 @@ nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)
case TC_SETUP_QDISC_ETS:
return nsim_setup_tc_ets(dev, type_data);
case TC_SETUP_BLOCK:
- return flow_block_cb_setup_simple(type_data,
- &nsim_block_cb_list,
- nsim_setup_tc_block_cb,
- ns, ns, true);
+ mutex_lock(&nsim_block_cb_lock);
+ err = flow_block_cb_setup_simple(type_data,
+ &nsim_block_cb_list,
+ nsim_setup_tc_block_cb,
+ ns, ns, true);
+ mutex_unlock(&nsim_block_cb_lock);
+ return err;
case TC_SETUP_FT:
return 0;
default:
--
2.43.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-07-19 17:50 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-19 17:50 [PATCH net] netdevsim: tc: serialize access to nsim_block_cb_list Weiming Shi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox