mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net] net/sched: release old template when replacing a chain
@ 2026-11-09 12:14 shaos
  2026-11-11 12:17 ` netdev-bot+sashiko
  0 siblings, 1 reply; 2+ messages in thread
From: shaos @ 2026-11-09 12:14 UTC (permalink / raw)
  To: jhs, jiri
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, netdev, linux-kernel

Hello,

An action-held traffic-control chain can remain alive after
RTM_DELCHAIN because a goto-chain action still references it.
RTM_NEWCHAIN can reuse the chain. When a new template is supplied,
tc_chain_tmplt_add() creates a template and overwrites the existing
chain->tmplt_ops and chain->tmplt_priv without destroying the old
one.

The old struct fl_flow_tmplt allocation (1160 bytes) becomes
unreachable, along with its classifier module reference. Each repeated
chain recreation leaks one object from kmalloc-2k. The allocation uses
GFP_KERNEL without __GFP_ACCOUNT, and the tested objects remain after
the network namespace that created them is destroyed.

A local user with permission to create unprivileged user and network
namespaces can obtain CAP_NET_ADMIN inside the child network namespace
and trigger the leak without packet traffic or a race. The demonstrated
impact is unbounded host-global kernel memory consumption; no memory
corruption or privilege escalation is demonstrated.

Two fresh QEMU boots of the unpatched Linux 7.3 tree showed
kmalloc-2k active objects increasing from 60 to 192 after 128 cycles.
The no-action and held-chain/no-template controls remained at 60. A
UID 1000 user+network namespace run increased the count from 48 to 204;
the matching control increased it from 48 to 84.

With this patch, two fresh 128-cycle positive boots remained at 60,
and both controls remained at 60. The user-namespace positive and
control runs both showed the same 48-to-84 setup delta, with no
per-cycle increase. The positive PoC reports a failed leak threshold on
the patched kernel because it is written to expect the vulnerable
behavior; the zero delta is the expected fixed result.

The issue was found during an LLM-assisted source review and confirmed
with a userspace PoC in a disposable QEMU VM.

HEAD commit:    c03c1a14507dfaf8b856c2608f9ac216021fc222
Git tree:       30fd2ef82912c26cf3a58ad0ba6afc375fa851ac
Source version: Linux 7.3.0
Compiler:       gcc 11.4.0, GNU ld 2.38

The console output, kernel config, reproducer, namespace launcher, and
patched-kernel validation logs are available here:
Console output:
https://gist.githubusercontent.com/shaos26/3e31c231ca56bc53ef80b5c8aada2821/raw/7ff5d84b07e0b260952d2f8575ffb1936edcb099/console-output.txt
Kernel config:
https://gist.githubusercontent.com/shaos26/3e31c231ca56bc53ef80b5c8aada2821/raw/aeed6e5360a23b7e36cc06272dc0069f8639c61f/kernel-config.txt
Reproducer:
https://gist.githubusercontent.com/shaos26/3e31c231ca56bc53ef80b5c8aada2821/raw/f73bf112b5d6bd7e6633963e3dee0c0083ffeef0/reproducer.sh
User namespace launcher:
https://gist.githubusercontent.com/shaos26/3e31c231ca56bc53ef80b5c8aada2821/raw/b30237aa0b52e39ebb9da06d790c3f8430b62903/userns_launcher.c
Patched validation:
https://gist.githubusercontent.com/shaos26/3e31c231ca56bc53ef80b5c8aada2821/raw/d769d8afbfa6293e3f7bff967a3408521972dcb5/patch-validation.txt

Run the reproducer as root, or with CAP_NET_ADMIN in a disposable
network namespace, on an unpatched kernel with BusyBox and iproute2:

    ./reproducer.sh positive 128
    ./reproducer.sh control-no-action 128
    ./reproducer.sh control-held-no-template 128

The user-namespace test used userns_launcher.c inside the test
initramfs. It drops to UID 1000 before creating the user and network
namespaces, then runs the same positive trigger.

The patch creates a replacement template first, leaving the old one
intact if creation fails. After successful creation it destroys the
old template and drops its module reference before installing the new
pointer pair.

Fixes: 9f407f1768d3 ("net: sched: introduce chain templates")
Signed-off-by: shaos <shawnq1@163.com>
---
 net/sched/cls_api.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index a9f54988561f2..56a706b3dbcab 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -3128,6 +3128,8 @@ static int tc_chain_tmplt_add(struct tcf_chain *chain, struct net *net,
 		module_put(ops->owner);
 		return PTR_ERR(tmplt_priv);
 	}
+	/* An action-held chain can retain a template after RTM_DELCHAIN. */
+	tc_chain_tmplt_del(chain->tmplt_ops, chain->tmplt_priv);
 	chain->tmplt_ops = ops;
 	chain->tmplt_priv = tmplt_priv;
 	return 0;


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

end of thread, other threads:[~2026-11-11 12:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-09 12:14 [PATCH net] net/sched: release old template when replacing a chain shaos
2026-11-11 12:17 ` netdev-bot+sashiko

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

all inboxes | Powered by JetHome®