CVE-2026-74700
Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
22/08/2026
Última modificación:
22/08/2026
Descripción
*** Pendiente de traducción *** In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
net/sched: cls_api: Always acquire rtnl_lock when destroying locked classifiers<br />
<br />
Another challenge with unlocked filters.<br />
There is a short window in tc_new_tfilter where a tcf_proto can be found<br />
and briefly referenced by a totally unrelated, unlocked classifier&#39;s request<br />
and cause a race.<br />
<br />
Feng created a poc which created this race with two threads, one creating a<br />
u32 filter and other a flower filter in the same chain/prio:<br />
<br />
1. Both threads enter tc_new_tfilter, both find the chain empty, both<br />
drop filter_chain_lock<br />
2. u32 finishes tcf_proto_create("u32") first, calls<br />
tcf_chain_tp_insert_unique() -> inserts u32_tp into the chain<br />
3. flower finishes tcf_proto_create("flower") later, calls<br />
tcf_chain_tp_insert_unique() -> tcf_chain_tp_find() now sees u32_tp<br />
already there, takes a reference on it, destroys flower&#39;s own tp_new<br />
and returns u32_tp to the caller.<br />
<br />
Flower then hits the kind mismatch check (because it requested for kind<br />
"flower" but tp->ops->kind is "u32") and goes through the errout path<br />
which calls tcf_proto_put() on u32_tp. If the u32 thread has already<br />
gone through its own errout (its change() call failed on the PoC&#39;s empty<br />
options) and dropped its create and insert refs, flower&#39;s put is the<br />
last one and drops u32_tp&#39;s refcnt to zero.<br />
<br />
At this point tp->ops->destroy() runs in a context that never took<br />
rtnl_lock. When that happens, it might cause a UAF like the following<br />
(illustrated by the PoC):<br />
<br />
[ +0.000710] BUG: KASAN: slab-use-after-free in u32_init (net/sched/cls_u32.c:393)<br />
[ +0.000281] Read of size 8 at addr ffff888120022f00 by task poc_feng_xue/524<br />
<br />
Call Trace:<br />
u32_init (net/sched/cls_u32.c:393)<br />
tc_new_tfilter (net/sched/cls_api.c:2378)<br />
<br />
Allocated by task 526:<br />
u32_init (net/sched/cls_u32.c:378)<br />
tc_new_tfilter (net/sched/cls_api.c:2378)<br />
<br />
Freed by task 522:<br />
kfree<br />
u32_destroy (net/sched/cls_u32.c:662)<br />
tcf_proto_destroy (net/sched/cls_api.c:446)<br />
tcf_proto_put (net/sched/cls_api.c:459)<br />
tc_new_tfilter (net/sched/cls_api.c:2459)<br />
<br />
Fix this by having tcf_proto_destroy() take rtnl_lock around<br />
tp->ops->destroy() for locked classifiers whenever rtnl is not held.<br />
<br />
To explain why I used a temp variable "not_lockless" I&#39;d like to point to a<br />
semi-related note on rtnl_held vs TCF_PROTO_OPS_DOIT_UNLOCKED (adding here<br />
for future cleanup if deemed necessary):<br />
The rtnl_held parameter and the TCF_PROTO_OPS_DOIT_UNLOCKED flag are<br />
redundant sources of truth for whether rtnl_lock is held. Among the nine<br />
classifier destroy(..rtnl_held..) callbacks, only flower consults the<br />
rtnl_held parameter which it propagates to tc_setup_cb_destroy()<br />
and tc_setup_cb_call(). The other eight (u32, flow, bpf, cgroup, route, basic,<br />
fw, mall) ignore it entirely;-> those that call tc_setup_cb_destroy()<br />
(u32, bpf, mall) hardcode true always instead of forwarding the parameter.<br />
<br />
A future cleanup should remove the rtnl_held parameter from the destroy callback<br />
signature entirely and have callers rely solely on their knowledge whether<br />
they are running in an unlocked context.
Impacto
Referencias a soluciones, herramientas e información
- https://git.kernel.org/stable/c/34e77d8e3570f9df3952496ddb402833695662fd
- https://git.kernel.org/stable/c/a347304b2ca1a5377d5bd2d8a72e4b4f12afe648
- https://git.kernel.org/stable/c/a81f9c44d87fb59d99fce72e29e02cab3a49a1c3
- https://git.kernel.org/stable/c/b648c8a56531aeabd1c14f6b5cf1891e269b3756
- https://git.kernel.org/stable/c/d6222af7274f08e7a1848131dc30319993d8f377


