Reported by shaos with a reproducer, which was reproduced and verified in our test environment. The issue: The teql master devices are created once in the initial network namespace and their Qdisc_ops are global. teql_qdisc_init() takes the teql_master embedded in the registered sch->ops and uses it without checking whether the new qdisc's device lives in the same network namespace as the master. A qdisc created in another netns can therefore attach to the init-net master and change its MTU and flags. The Fix: Reject a teql qdisc whose device is not in the master's network namespace with -EOPNOTSUPP and an extack message; same-netns teql still works. Initialize the private skb queue before any validation so every constructor failure path, including qdisc_create_dflt(), which resets the qdisc before destroying it, sees an initialized empty queue. Conditions to recreate the bug: CONFIG_NET_SCH_TEQL=y, CONFIG_DUMMY=y, CONFIG_USER_NS=y, CONFIG_NET_NS=y. As an unprivileged UID, unshare a user and network namespace, create a dummy device, set its MTU to 60000, and add a root teql0 qdisc: unshare -Urn ip link add dummy0 type dummy ip link set dummy0 mtu 60000 tc qdisc add dev dummy0 root teql0 The init-net teql0 device changes from MTU 1500 to 60000. A pfifo control on the same device leaves the MTU unchanged, and a direct MTU change on init-net teql0 is denied. The namespace needs CAP_NET_ADMIN; no init-net privilege is required. With the fix the attach fails with "Operation not supported" and the init-net MTU stays 1500. Fixes: 7316ae88c43d ("net_sched: make traffic control network namespace aware") Reported-by: shaos Link: https://lore.kernel.org/netdev/20261022144830.67948-1-shawnq1@163.com/ Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/SER-NSBD.v1.r2.20261031160050-3%40mojatatu.com Cc: stable@vger.kernel.org Reviewed-by: Victor Nogueira Signed-off-by: Jamal Hadi Salim --- v2: considers comments from Sashiko (nipa) on the repost2 posting: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/SER-NSBD.v1.r2.20261031160050-3%40mojatatu.com The cross-netns check ran before the "teql can only be used as root" check, so every case it did not catch was answered by that check, masking the assertion that tc-testing case 124e makes. The root-parent validation now runs first and the namespace check second; 4/4 adds a case that covers the namespace rejection on its own. net/sched/sch_teql.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 70c948a26f80..dc21cd9704a2 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -200,6 +200,8 @@ static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt, struct Qdisc *first; unsigned long flags; + skb_queue_head_init(&q->q); + if (dev->hard_header_len > m->dev->hard_header_len) return -EINVAL; @@ -211,9 +213,12 @@ static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt, return -EOPNOTSUPP; } - q->m = m; + if (dev_net(dev) != dev_net(m->dev)) { + NL_SET_ERR_MSG_MOD(extack, "teql master is in a different network namespace"); + return -EOPNOTSUPP; + } - skb_queue_head_init(&q->q); + q->m = m; raw_spin_lock_irqsave(&m->slaves_lock, flags); first = rcu_dereference_protected(m->slaves, lockdep_is_held(&m->slaves_lock)); -- 2.43.0