public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net 1/3] net/sched: cls_fw: fix NULL pointer dereference on shared blocks
@ 2026-03-27  6:12 Xiang Mei
  2026-03-27  6:12 ` [PATCH net 2/3] net/sched: cls_flow: " Xiang Mei
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Xiang Mei @ 2026-03-27  6:12 UTC (permalink / raw)
  To: netdev; +Cc: jhs, jiri, davem, edumazet, kuba, horms, shuah, bestswngs,
	Xiang Mei

The old-method path in fw_classify() calls tcf_block_q() and
dereferences q->handle. Shared blocks leave block->q NULL, causing a
NULL deref when an empty cls_fw filter is attached to a shared block
and a packet with a nonzero major skb mark is classified.

Check tcf_block_shared() before accessing block->q and return -1 (no
match) for shared blocks, consistent with cls_u32's tc_u_common_ptr().

The fixed null-ptr-deref calling stack:
 KASAN: null-ptr-deref in range [0x0000000000000038-0x000000000000003f]
 RIP: 0010:fw_classify (net/sched/cls_fw.c:81)
 Call Trace:
  tcf_classify (./include/net/tc_wrapper.h:197 net/sched/cls_api.c:1764 net/sched/cls_api.c:1860)
  tc_run (net/core/dev.c:4401)
  __dev_queue_xmit (net/core/dev.c:4535 net/core/dev.c:4790)

Fixes: 1abf272022cf ("net: sched: tcindex, fw, flow: use tcf_block_q helper to get struct Qdisc")
Reported-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Xiang Mei <xmei5@asu.edu>
---
 net/sched/cls_fw.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index be81c108179d..caf17ab3be87 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -74,9 +74,14 @@ TC_INDIRECT_SCOPE int fw_classify(struct sk_buff *skb,
 			}
 		}
 	} else {
-		struct Qdisc *q = tcf_block_q(tp->chain->block);
+		struct tcf_block *block = tp->chain->block;
+		struct Qdisc *q;
+
+		if (tcf_block_shared(block))
+			return -1;
 
 		/* Old method: classify the packet using its skb mark. */
+		q = tcf_block_q(block);
 		if (id && (TC_H_MAJ(id) == 0 ||
 			   !(TC_H_MAJ(id ^ q->handle)))) {
 			res->classid = id;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread
* [PATCH] net/sched: skip reverse bind walk after failed class delete
@ 2026-03-29 16:53 Qi Tang
  2026-03-29 18:21 ` Jamal Hadi Salim
  0 siblings, 1 reply; 11+ messages in thread
From: Qi Tang @ 2026-03-29 16:53 UTC (permalink / raw)
  To: Jamal Hadi Salim, Jiri Pirko
  Cc: Cong Wang, David S . Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, netdev, Qi Tang

__tc_ctl_tclass() unconditionally calls tc_bind_tclass() after
RTM_DELTCLASS even when tclass_del_notify() fails.  On
ingress/clsact qdiscs with shared blocks, the delete always fails
with -EOPNOTSUPP, but the subsequent bind walk still runs.
tc_bind_tclass() reaches tcf_node_bind() which calls tcf_block_q()
on the shared block and dereferences the NULL qdisc pointer.

Only perform the reverse bind walk when the class delete succeeds.

Triggered by issuing RTM_DELTCLASS on an ingress/clsact pseudo-class
that carries a shared block with a classifier using bind_class:

  $ tc qdisc add dev veth0 egress_block 22 clsact
  $ tc filter add block 22 pref 1 protocol ip handle 0x1 \
      fw classid ffff:fff3 action drop
  $ tc class del dev veth0 classid ffff:fff3
  RTNETLINK answers: Operation not supported
  Kernel panic - not syncing: Attempted to kill init!
  exitcode=0x00000700

The NULL dereference occurs in tcf_node_bind() when sch_tree_lock()
is called with the NULL return from tcf_block_q() on a shared block.

Fixes: 07d79fc7d94e ("net_sched: add reverse binding for tc class")
Signed-off-by: Qi Tang <tpluszz77@gmail.com>
---
 net/sched/sch_api.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index cc43e3f7574f..50d311ff1f2d 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -2251,7 +2251,8 @@ static int __tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n,
 		case RTM_DELTCLASS:
 			err = tclass_del_notify(net, cops, skb, n, q, cl, extack);
 			/* Unbind the class with flilters with 0 */
-			tc_bind_tclass(q, portid, clid, 0);
+			if (!err)
+				tc_bind_tclass(q, portid, clid, 0);
 			goto out;
 		case RTM_GETTCLASS:
 			err = tclass_get_notify(net, skb, n, q, cl, extack);
-- 
2.43.0


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

end of thread, other threads:[~2026-03-31  5:04 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-27  6:12 [PATCH net 1/3] net/sched: cls_fw: fix NULL pointer dereference on shared blocks Xiang Mei
2026-03-27  6:12 ` [PATCH net 2/3] net/sched: cls_flow: " Xiang Mei
2026-03-27  6:13 ` [PATCH net 3/3] selftests/tc-testing: add tests for cls_fw and cls_flow " Xiang Mei
2026-03-27 14:11 ` [PATCH net 1/3] net/sched: cls_fw: fix NULL pointer dereference " Jamal Hadi Salim
2026-03-29 12:15   ` Jamal Hadi Salim
2026-03-29 18:52     ` Xiang Mei
2026-03-30 16:45       ` Jamal Hadi Salim
2026-03-31  5:04         ` Xiang Mei
2026-03-30 13:40     ` [PATCH] net/sched: skip reverse bind walk after failed class delete Qi Tang
  -- strict thread matches above, loose matches on Subject: below --
2026-03-29 16:53 Qi Tang
2026-03-29 18:21 ` Jamal Hadi Salim

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