Netdev List
 help / color / mirror / Atom feed
* [PATCH] net/sched: cls_api: skip indr register on failed bind
@ 2026-10-13 16:30 Qihang
  2026-10-13 16:35 ` netdev-bot+sinfo
  0 siblings, 1 reply; 2+ messages in thread
From: Qihang @ 2026-10-13 16:30 UTC (permalink / raw)
  To: netdev
  Cc: jhs, jiri, davem, edumazet, kuba, pabeni, horms, elic, stable,
	Qihang

Binding a device without ndo_setup_tc() to a shared block that already
offloads records the block on flow_indir_dev_list and then fails.  Nothing
removes that record, so once the block is destroyed the next
flow_indr_dev_register() splices a list into freed memory:

  tcf_block_offload_cmd()
    -> flow_indr_dev_setup_offload()
       -> indir_dev_add()   [ record: data = block,
                                cb_list = &block->flow_block.cb_list ]
    -> return -EOPNOTSUPP
  tcf_block_offload_bind()
    -> tcf_block_offload_in_use(block) is true    [ offloadcnt > 0 ]
    -> return -EOPNOTSUPP
  tcf_block_get_ext()
    -> err_block_offload_bind            [ no tcf_block_offload_unbind() ]

Only a FLOW_BLOCK_UNBIND calls indir_dev_remove(), and the failed bind
never issues one.  The next flow_indr_dev_register() replays the record
through existing_qdiscs_register(), where list_splice() writes the new
linkage into the freed block's cb_list; the callback that the replay
allocates keeps indr.data pointing at the freed block, so a later driver
unregister reaches tc_block_indr_cleanup() on it as well.

The fix was built and the reproducer re-run clean on it.

Fix by returning -EOPNOTSUPP before flow_indr_dev_setup_offload() when the
command is FLOW_BLOCK_BIND and the block is already offloading, which is
the condition tcf_block_offload_bind() rejects the bind with, so that no
record is created.  Keep the check limited to the bind: on unbind this
branch is the only caller of indir_dev_remove(), and it runs while
offloadcnt is still non-zero.

Fixes: 74fc4f828769c ("net: Fix offloading indirect devices dependency on qdisc order creation")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Qihang <q.h.hack.winter@gmail.com>
---
 net/sched/cls_api.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index a9f54988561f..7acfe71853a7 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -860,6 +860,10 @@ static int tcf_block_offload_cmd(struct tcf_block *block,
 		return tcf_block_setup(block, &bo);
 	}
 
+	/* a bind that cannot succeed must not leave a record behind */
+	if (command == FLOW_BLOCK_BIND && tcf_block_offload_in_use(block))
+		return -EOPNOTSUPP;
+
 	flow_indr_dev_setup_offload(dev, sch, TC_SETUP_BLOCK, block, &bo,
 				    tc_block_indr_cleanup);
 	tcf_block_setup(block, &bo);
-- 
2.54.0 (Apple Git-157)


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-13 16:35 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-13 16:30 [PATCH] net/sched: cls_api: skip indr register on failed bind Qihang
2026-10-13 16:35 ` netdev-bot+sinfo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox