CVE
CVE-2026-53264
CWE
CWE-362, CWE-416
Affected Surface
- Linux kernels from `4.14` upward until the relevant upstream fixed lines, including `< 5.10.259`, `5.11.x < 5.15.210`, `5.16.x < 6.1.176`, `6.2.x < 6.6.143`, `6.7.x < 6.12.94`, `6.13.x < 6.18.36`, and `6.19.x < 7.0.13`
- Enterprise and developer Linux distributions that expose the vulnerable `net/sched` action lifecycle and have not yet backported the RCU-deferred free fix into their shipping kernel packages
- Developer workstations, self-hosted CI runners, shared Linux bastions, lab systems, and container hosts where untrusted local code can create user namespaces and reach traffic-control netlink operations
- Hosts that also expose the same public exploit preconditions called out by STAR Labs, including `clsact` / `flower` paths and action modules such as `CONFIG_NET_ACT_GACT`
CVE-2026-53264 is the most defensible new /research candidate from the last three days because the public exploit analysis only landed at the end of July, it is not yet covered in this repository, and it matters directly to application-security teams that operate Linux developer hosts or CI runners. The bug lives in the Linux kernel’s traffic-control subsystem rather than in npm or PyPI, but that is exactly why it matters: once a malicious package, a compromised build step, or a low-privilege application bug gets local code execution, this kernel flaw can provide the host-root second stage.
What changed this week was not the existence of the bug alone. The important late-July development was STAR Labs’ public exploit write-up showing how the net/sched race can be turned into a practical local privilege escalation on CentOS Stream 9, together with fresh NVD/CISA enrichment that tightened the affected ranges and exploit metadata. For defenders, that moves the issue from “patched kernel bug in metadata feeds” to “publicly explained exploitation chain you should actively model against Linux build and workstation fleets.”
What is affected
The affected project is the Linux kernel, specifically the net/sched action lifecycle in include/net/act_api.h and net/sched/act_api.c. Public vulnerability metadata now tracks the issue from Linux 4.14 onward, with the first upstream fixed versions in each maintained stable line shown below:
| Upstream line | First fixed release |
|---|---|
4.14 through 5.10.x | 5.10.259 |
5.11.x through 5.15.x | 5.15.210 |
5.16.x through 6.1.x | 6.1.176 |
6.2.x through 6.6.x | 6.6.143 |
6.7.x through 6.12.x | 6.12.94 |
6.13.x through 6.18.x | 6.18.36 |
6.19.x through 7.0.x | 7.0.13 |
Distribution backports still matter more than raw uname -r output, but those stable cut points are the right starting point for scoping. If you maintain:
- self-hosted CI runners on Linux,
- shared developer workstations,
- bastions or multi-user engineering hosts,
- container hosts where workloads can already execute local code,
then this is the kind of kernel issue that deserves AppSec attention even though it is “local.” A poisoned dependency does not need a remote kernel entrypoint if it already has a shell.
Root cause: RCU-protected lookup, immediate free
The vulnerable flow is conceptually simple. tcf_idr_check_alloc() looks up a shared tc_action object under rcu_read_lock(), then tries to take a live reference:
rcu_read_lock();
p = idr_find(&idrinfo->action_idr, *index);
...
if (!refcount_inc_not_zero(&p->tcfa_refcnt)) {
rcu_read_unlock();
return -EAGAIN;
}
That lookup path assumes RCU will protect readers long enough to make the refcount check meaningful. The bug is that the delete side can drop the last reference and free the object immediately instead of deferring the free until after the RCU grace period. In the vulnerable path, CPU0 can still be holding p from idr_find() while CPU1 has already removed and kfree()d it.
That is why the NVD change record explicitly describes the race as:
CPU0: p = idr_find(idr, index)
CPU1: idr_remove(idr, index); tcf_action_cleanup(p); kfree(p)
CPU0: refcount_inc_not_zero(&p->tcfa_refcnt) <-- UAF
The fix is small but precise. Instead of freeing the action immediately, the patched path restores RCU-delayed destruction:
struct tc_action {
...
struct rcu_head tcfa_rcu;
...
}
static void free_tcf(struct tc_action *p)
{
...
kfree_rcu(p, tcfa_rcu);
}
That change closes the exact security gap that exploitation needs. After idr_remove(), the object is no longer reachable to new lookups, but existing readers also no longer race a raw kfree() while they still hold an RCU-protected pointer.
Why the public exploit path matters to AppSec teams
STAR Labs’ write-up is what makes this worth a new article instead of a quiet note in a weekly briefing. The published exploit does not rely on already being root or on obscure hardware behavior. It shows how a local attacker can move from ordinary userland execution to kernel control by:
- creating a separate user namespace to gain
CAP_NET_ADMINrelative to the relevant netlink path; - using
RTM_NEWTFILTERandRTM_DELTFILTERinstead of the less reachable action-management API; - choosing a
clsactqdisc andflowerfilter path so the operation avoids the heavierrtnl_lock()path; - racing binder and deleter threads around a shared action index;
- reclaiming the freed
kmalloc-256victim withKEYCTL_UPDATE-drivenuser_key_payloadobjects; - pivoting through the reclaimed
opsvtable entry whentcf_action_fill_size()dereferencesact->ops->get_fill_size.
The public write-up is explicit about the exploitation prerequisites:
requires CONFIG_NET_ACT_GACT=y or m
requires CONFIG_NET_CLS_FLOWER=y or m
requires unprivileged user namespaces to be enabled
That does not mean only specialized research boxes are at risk. It means the exploit path is especially relevant on the exact Linux systems AppSec teams already worry about: developer desktops, test environments, CI workers, and lab machines that carry broad kernel feature coverage and where user namespaces are often available for containers or sandboxed tooling.
The race is not theoretical
The most useful part of the STAR Labs analysis is not the buzzword about AI-assisted bug hunting. It is the exploit engineering detail that shows the bug is not just a crash primitive.
The binder thread abuses the error path in tcf_action_init() by asking for two actions: one real shared action index and one intentionally malformed action. That causes the target action to be fetched during initialization, but the filter never commits:
for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
act = tcf_action_init_1(...); // fetch action
if (IS_ERR(act)) {
err = PTR_ERR(act);
goto err; // abort before insert_many
}
actions[i - 1] = act;
}
tcf_idr_insert_many(actions, init_res);
That matters because it gives the attacker repeated low-overhead opportunities to hit tcf_idr_check_alloc() without paying the cost of a full create-and-delete cycle for every race attempt. The deleter thread only needs to keep re-inserting and removing the same action index.
Once the freed tc_action lands back in kmalloc-256, the write-up shows how repeated KEYCTL_UPDATE operations reclaim it as user_key_payload data, overlapping attacker-controlled bytes with the ops vtable pointer. The final published chain then overwrites core_pattern and crashes a child process so Linux executes a memfd-backed payload as the core-dump handler in the init namespace. That is a very Linux-specific route to root, but it is also a very practical one.
The operational takeaway is simple: the public analysis demonstrates a route from local code execution to full host compromise, not just a kernel oops.
Why this should sit in a software-supply-chain research library
Kernel privilege escalations like CVE-2026-53264 are part of the software-supply-chain story whenever the first-stage foothold is developer tooling or CI:
- a malicious npm dependency lands on a Linux build runner;
- a compromised PyPI wheel is imported on a researcher workstation;
- a poisoned GitHub Action step drops a low-privilege shell on a self-hosted runner;
- an internal app bug yields local execution inside a user account on a shared engineering host.
In each case, the kernel becomes the trust-boundary breaker. That is why this belongs alongside package-compromise research instead of in a separate “OS bugs only” bucket.
Detection and scoping
Start by checking whether the host is even on a vulnerable kernel line and whether the public exploit prerequisites are plausible:
uname -r
sysctl kernel.unprivileged_userns_clone 2>/dev/null
rg 'CONFIG_NET_(ACT_GACT|CLS_FLOWER)' "/boot/config-$(uname -r)"
If your kernel config lives elsewhere, adapt accordingly. For module-based builds, confirm whether the relevant traffic-control modules are available:
modinfo act_gact 2>/dev/null
modinfo cls_flower 2>/dev/null
Then inspect vendor changelogs rather than trusting version strings alone:
rpm -q --changelog kernel | rg 'CVE-2026-53264|act_api: use RCU with deferred freeing'
apt changelog "linux-image-$(uname -r)" 2>/dev/null | \
rg 'CVE-2026-53264|act_api: use RCU with deferred freeing'
Prioritize systems where all of the following are true:
- untrusted or semi-trusted code can execute locally;
- user namespaces are enabled or widely relied upon;
- the kernel line is still vulnerable or backport status is unknown;
- the host is high-value enough that local root changes the incident materially.
That set usually includes self-hosted runners and shared developer Linux boxes before it includes tightly locked-down production appliances.
Remediation
Patch to a vendor kernel that includes the kfree_rcu()-based fix and reboot into it. Do not stop at package installation; confirm the running kernel is the remediated one.
If you need short-term exposure reduction while patching rolls out, the public exploit analysis points to the most relevant friction points:
- restrict or disable unprivileged user namespaces where that does not break required workloads;
- reduce availability of traffic-control capabilities on shared hosts;
- treat Linux developer workstations and self-hosted CI runners as high-priority kernel patch targets, not just server fleets.
Those are compensating controls, not a substitute for the fixed kernel. The public write-up already showed a reliable route to root on a mainstream enterprise Linux target, and NVD now captures the exact fixed stable lines needed for triage.
For AppSec teams, the lesson is broader than one CVE: whenever a dependency incident or CI compromise yields “only” local code execution on Linux, you should immediately ask which kernel privilege amplifiers are still present on that host. CVE-2026-53264 is the newest reminder that the answer can still be “enough to become root.”
From research to remediation
Check whether this pattern exists in your codebase
Turn this research into a remediation workflow. Scan dependencies and package manifests for similar supply-chain risk, then prioritize fixes with reachability context.