* [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
* Re: [PATCH] net/sched: cls_api: skip indr register on failed bind
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
0 siblings, 0 replies; 2+ messages in thread
From: netdev-bot+sinfo @ 2026-10-13 16:35 UTC (permalink / raw)
To: Qihang
Cc: netdev, jhs, jiri, davem, edumazet, kuba, pabeni, horms, elic,
stable
Hi!
This is an automated message. This series looks like a fix, but its
commit messages seem to be missing some information:
- How the issue was discovered, e.g. hit in production, hit during
development, syzbot report, manual code inspection, LLM or static
analysis tool scan.
Please do not repost the series just to address the above. Instead,
reply to this email with the missing information, so that reviewers
can take it into account. If the series needs another revision for
other reasons, please include the information in the commit messages
then.
The evaluation is done by an LLM so it may be wrong, if you think
that is the case please reply and explain.
^ permalink raw reply [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