Skip to content

Commit 380ad8b

Browse files
vbnogueiragregkh
authored andcommitted
net/sched: Only allow act_ct to bind to clsact/ingress qdiscs and shared blocks
commit 11cb63b upstream. 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: 3f14b37 ("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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 04d7552 commit 380ad8b

3 files changed

Lines changed: 14 additions & 0 deletions

File tree

include/net/act_api.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ struct tc_action {
7070
#define TCA_ACT_FLAGS_REPLACE (1U << (TCA_ACT_FLAGS_USER_BITS + 2))
7171
#define TCA_ACT_FLAGS_NO_RTNL (1U << (TCA_ACT_FLAGS_USER_BITS + 3))
7272
#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))
7374

7475
/* Update lastuse only if needed, to avoid dirtying a cache line.
7576
* We use a temp variable to avoid fetching jiffies twice.

net/sched/act_ct.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,6 +1358,12 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla,
13581358
return -EINVAL;
13591359
}
13601360

1361+
if (bind && !(flags & TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT)) {
1362+
NL_SET_ERR_MSG_MOD(extack,
1363+
"Attaching ct to a non ingress/clsact qdisc is unsupported");
1364+
return -EOPNOTSUPP;
1365+
}
1366+
13611367
err = nla_parse_nested(tb, TCA_CT_MAX, nla, ct_policy, extack);
13621368
if (err < 0)
13631369
return err;

net/sched/cls_api.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2228,6 +2228,11 @@ static bool is_qdisc_ingress(__u32 classid)
22282228
return (TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_INGRESS));
22292229
}
22302230

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+
22312236
static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
22322237
struct netlink_ext_ack *extack)
22332238
{
@@ -2420,6 +2425,8 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
24202425
flags |= TCA_ACT_FLAGS_NO_RTNL;
24212426
if (is_qdisc_ingress(parent))
24222427
flags |= TCA_ACT_FLAGS_AT_INGRESS;
2428+
if (is_ingress_or_clsact(block, q))
2429+
flags |= TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT;
24232430
err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh,
24242431
flags, extack);
24252432
if (err == 0) {

0 commit comments

Comments
 (0)