Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net/sched: Only allow act_ct to bind to clsact/ingress qdiscs and shared blocks

As Paolo said earlier [1]:

"Since the blamed commit below, classify can return TC_ACT_CONSUMED while
the current skb being held by the defragmentation engine. As reported by
GangMin Kim, if such packet is that may cause a UaF when the defrag engine
later on tries to tuch again such packet."

act_ct was never meant to be used in the egress path, however some users
are attaching it to egress today [2]. Attempting to reach a middle
ground, we noticed that, while most qdiscs are not handling
TC_ACT_CONSUMED, clsact/ingress qdiscs are. With that in mind, we
address the issue by only allowing act_ct to bind to clsact/ingress
qdiscs and shared blocks. That way it's still possible to attach act_ct to
egress (albeit only with clsact).

[1] https://lore.kernel.org/netdev/674b8cbfc385c6f37fb29a1de08d8fe5c2b0fbee.1771321118.git.pabeni@redhat.com/
[2] https://lore.kernel.org/netdev/cc6bfb4a-4a2b-42d8-b9ce-7ef6644fb22b@ovn.org/

Reported-by: GangMin Kim <km.kim1503@gmail.com>
Fixes: 3f14b377d01d ("net/sched: act_ct: fix skb leak and crash on ooo frags")
CC: stable@vger.kernel.org
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/20260225134349.1287037-1-victor@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Victor Nogueira and committed by
Jakub Kicinski
11cb63b0 ba147986

+14
+1
include/net/act_api.h
··· 70 70 #define TCA_ACT_FLAGS_REPLACE (1U << (TCA_ACT_FLAGS_USER_BITS + 2)) 71 71 #define TCA_ACT_FLAGS_NO_RTNL (1U << (TCA_ACT_FLAGS_USER_BITS + 3)) 72 72 #define TCA_ACT_FLAGS_AT_INGRESS (1U << (TCA_ACT_FLAGS_USER_BITS + 4)) 73 + #define TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT (1U << (TCA_ACT_FLAGS_USER_BITS + 5)) 73 74 74 75 /* Update lastuse only if needed, to avoid dirtying a cache line. 75 76 * We use a temp variable to avoid fetching jiffies twice.
+6
net/sched/act_ct.c
··· 1360 1360 return -EINVAL; 1361 1361 } 1362 1362 1363 + if (bind && !(flags & TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT)) { 1364 + NL_SET_ERR_MSG_MOD(extack, 1365 + "Attaching ct to a non ingress/clsact qdisc is unsupported"); 1366 + return -EOPNOTSUPP; 1367 + } 1368 + 1363 1369 err = nla_parse_nested(tb, TCA_CT_MAX, nla, ct_policy, extack); 1364 1370 if (err < 0) 1365 1371 return err;
+7
net/sched/cls_api.c
··· 2228 2228 return (TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_INGRESS)); 2229 2229 } 2230 2230 2231 + static bool is_ingress_or_clsact(struct tcf_block *block, struct Qdisc *q) 2232 + { 2233 + return tcf_block_shared(block) || (q && !!(q->flags & TCQ_F_INGRESS)); 2234 + } 2235 + 2231 2236 static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n, 2232 2237 struct netlink_ext_ack *extack) 2233 2238 { ··· 2425 2420 flags |= TCA_ACT_FLAGS_NO_RTNL; 2426 2421 if (is_qdisc_ingress(parent)) 2427 2422 flags |= TCA_ACT_FLAGS_AT_INGRESS; 2423 + if (is_ingress_or_clsact(block, q)) 2424 + flags |= TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT; 2428 2425 err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh, 2429 2426 flags, extack); 2430 2427 if (err == 0) {