In the Linux kernel, the following vulnerability has been resolved:
sched/psi: fix race between file release and pressure write
A potential race condition exists between pressure write and cgroup file release regarding the priv member of struct kernfsopenfile, which triggers the uaf reported in [1].
Consider the following scenario involving execution on two separate CPUs:
CPU0 CPU1 ==== ==== vfsrmdir() kernfsioprmdir() cgrouprmdir() cgroupknlocklive() cgroupdestroylocked() cgroupaddrmfiles() cgrouprmfile() kernfsremovebyname() kernfsremovebynamens() vfs_write() _kernfsremove() newsyncwrite() kernfsdrain() kernfsfopwriteiter() kernfsdrainopenfiles() cgroupfilewrite() kernfsreleasefile() pressurewrite() cgroupfilerelease() ctx = of->priv; kfree(ctx); of->priv = NULL; cgroupknunlock() cgroupknlocklive() cgroupget(cgrp) cgroupknunlock() if (ctx->psi.trigger) // here, trigger uaf for ctx, that is of->priv
The cgrouprmdir() is protected by the cgroupmutex, it also safeguards the memory deallocation of of->priv performed within cgroupfilerelease(). However, the operations involving of->priv executed within pressurewrite() are not entirely covered by the protection of cgroupmutex. Consequently, if the code in pressurewrite(), specifically the section handling the ctx variable executes after cgroupfile_release() has completed, a uaf vulnerability involving of->priv is triggered.
Therefore, the issue can be resolved by extending the scope of the cgroupmutex lock within pressurewrite() to encompass all code paths involving of->priv, thereby properly synchronizing the race condition occurring between cgroupfilerelease() and pressure_write().
And, if an live kn lock can be successfully acquired while executing the pressure write operation, it indicates that the cgroup deletion process has not yet reached its final stage; consequently, the priv pointer within open_file cannot be NULL. Therefore, the operation to retrieve the ctx value must be moved to a point after the live kn lock has been successfully acquired.
In another situation, specifically after entering cgroupknlocklive() but before acquiring cgroupmutex, there exists a different class of race condition:
CPU0: write memory.pressure CPU1: write cgroup.pressure=0 =========================== =============================
kernfsfopwriteiter() kernfsgetactiveof(of) pressurewrite() cgroupknlocklive(memory.pressure) cgrouptryget(cgrp) kernfsbreakactiveprotection(kn) ... blocks on cgroup_mutex
cgroup_pressure_write()
cgroup_kn_lock_live(cgroup.pressure)
cgroup_file_show(memory.pressure, false)
kernfs_show(false)
kernfs_drain_open_files()
cgroup_file_release(of)
kfree(ctx)
of->priv = NULL
cgroup_kn_unlock()
... acquires cgroup_mutex ctx = of->priv; // may now be NULL if (ctx->psi.trigger) // NULL dereference
Consequently, there is a possibility that of->priv is NULL, the pressure write needs to check for this.
Now that the scope of the cgroupmutex has been expanded, the original explicit cgroupget/put operations are no longer necessary, this is because acquiring/releasing the live kn lock inherently executes a cgroup get/put operation.
[1] BUG: KASAN: slab-use-after-free in pressurewrite+0xa4/0x210 kernel/cgroup/cgroup.c:4011 Call Trace: pressurewrite+0xa4/0x210 kernel/cgroup/cgroup.c:4011 cgroupfilewrite+0x36f/0x790 kernel/cgroup/cgroup.c:43 ---truncated---
{
"osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/52xxx/CVE-2026-52991.json",
"cna_assigner": "Linux"
}