Description
In the Linux kernel, the following vulnerability has been resolved:

eventpoll: fix ep_remove struct eventpoll / struct file UAF

ep_remove() (via ep_remove_file()) cleared file->f_ep under
file->f_lock but then kept using @file inside the critical section
(is_file_epoll(), hlist_del_rcu() through the head, spin_unlock).
A concurrent __fput() taking the eventpoll_release() fastpath in
that window observed the transient NULL, skipped
eventpoll_release_file() and ran to f_op->release / file_free().

For the epoll-watches-epoll case, f_op->release is
ep_eventpoll_release() -> ep_clear_and_put() -> ep_free(), which
kfree()s the watched struct eventpoll. Its embedded ->refs
hlist_head is exactly where epi->fllink.pprev points, so the
subsequent hlist_del_rcu()'s "*pprev = next" scribbles into freed
kmalloc-192 memory.

In addition, struct file is SLAB_TYPESAFE_BY_RCU, so the slot
backing @file could be recycled by alloc_empty_file() --
reinitializing f_lock and f_ep -- while ep_remove() is still
nominally inside that lock. The upshot is an attacker-controllable
kmem_cache_free() against the wrong slab cache.

Pin @file via epi_fget() at the top of ep_remove() and gate the
critical section on the pin succeeding. With the pin held @file
cannot reach refcount zero, which holds __fput() off and
transitively keeps the watched struct eventpoll alive across the
hlist_del_rcu() and the f_lock use, closing both UAFs.

If the pin fails @file has already reached refcount zero and its
__fput() is in flight. Because we bailed before clearing f_ep,
that path takes the eventpoll_release() slow path into
eventpoll_release_file() and blocks on ep->mtx until the waiter
side's ep_clear_and_put() drops it. The bailed epi's share of
ep->refcount stays intact, so the trailing ep_refcount_dec_and_test()
in ep_clear_and_put() cannot free the eventpoll out from under
eventpoll_release_file(); the orphaned epi is then cleaned up
there.

A successful pin also proves we are not racing
eventpoll_release_file() on this epi, so drop the now-redundant
re-check of epi->dying under f_lock. The cheap lockless
READ_ONCE(epi->dying) fast-path bailout stays.
Published: 2026-05-30
Score: n/a
EPSS: < 1% Very Low
KEV: No
Impact: n/a
Action: n/a
AI Analysis

Impact

The vulnerability is a use‑after‑free in the Linux kernel’s epoll handling. During a call to ep_remove, the function clears the file->f_ep field and then continues to use the now‑NULL @file within a critical section. A concurrent reference‑count drop frees the file and its associated eventpoll structure while the removal routine still holds a reference, enabling an attacker to trigger a kmem_cache_free on freed memory. The freed memory can then be overwritten with attacker‑controlled data, which may lead to arbitrary kernel writes and privilege escalation. This flaw is identified as CWE‑416 and directly compromises the integrity of the kernel purge path, potentially allowing code execution or system crash.

Affected Systems

The flaw affects the Linux kernel itself, irrespective of distribution. All kernel versions compiled from source prior to the application of the patch are potentially vulnerable; the exact release numbers are not listed in the provided data. The issue arises in any build where the epoll subsystem is compiled and used.

Risk and Exploitability

The EPSS score is not available and the vulnerability is not listed in the CISA KEV catalog. The flaw requires a race condition that may be triggered by a local user with the ability to manipulate epoll watches, which is a high‑privilege attack scenario. Because it is a kernel‑level use‑after‑free, successful exploitation can lead to full root takeover or denial of service. The lack of public exploitation data suggests the risk is potentially high for any system that has not applied the patch, but it is constrained to systems that expose the epoll interface and run a vulnerable kernel.

Generated by OpenCVE AI on May 30, 2026 at 13:50 UTC.

Remediation

No vendor fix or workaround currently provided.

OpenCVE Recommended Actions

  • Apply the latest Linux kernel patch that fixes the ep_remove use‑after‑free and reboot
  • If an immediate kernel upgrade is not possible, disable or restrict access to the epoll interface or stop services that use it to eliminate the attack surface
  • Enable kernel hardening mitigations such as KASLR, SLUB randomization, mandatory access control (SELinux/AppArmor), and monitor system logs for EPOLL‑related crashes, applying subsequent security updates promptly

Generated by OpenCVE AI on May 30, 2026 at 13:50 UTC.

Tracking

Sign in to view the affected projects.

Advisories

No advisories yet.

History

Sat, 30 May 2026 14:15:00 +0000

Type Values Removed Values Added
Weaknesses CWE-416

Sat, 30 May 2026 12:45:00 +0000

Type Values Removed Values Added
Description In the Linux kernel, the following vulnerability has been resolved: eventpoll: fix ep_remove struct eventpoll / struct file UAF ep_remove() (via ep_remove_file()) cleared file->f_ep under file->f_lock but then kept using @file inside the critical section (is_file_epoll(), hlist_del_rcu() through the head, spin_unlock). A concurrent __fput() taking the eventpoll_release() fastpath in that window observed the transient NULL, skipped eventpoll_release_file() and ran to f_op->release / file_free(). For the epoll-watches-epoll case, f_op->release is ep_eventpoll_release() -> ep_clear_and_put() -> ep_free(), which kfree()s the watched struct eventpoll. Its embedded ->refs hlist_head is exactly where epi->fllink.pprev points, so the subsequent hlist_del_rcu()'s "*pprev = next" scribbles into freed kmalloc-192 memory. In addition, struct file is SLAB_TYPESAFE_BY_RCU, so the slot backing @file could be recycled by alloc_empty_file() -- reinitializing f_lock and f_ep -- while ep_remove() is still nominally inside that lock. The upshot is an attacker-controllable kmem_cache_free() against the wrong slab cache. Pin @file via epi_fget() at the top of ep_remove() and gate the critical section on the pin succeeding. With the pin held @file cannot reach refcount zero, which holds __fput() off and transitively keeps the watched struct eventpoll alive across the hlist_del_rcu() and the f_lock use, closing both UAFs. If the pin fails @file has already reached refcount zero and its __fput() is in flight. Because we bailed before clearing f_ep, that path takes the eventpoll_release() slow path into eventpoll_release_file() and blocks on ep->mtx until the waiter side's ep_clear_and_put() drops it. The bailed epi's share of ep->refcount stays intact, so the trailing ep_refcount_dec_and_test() in ep_clear_and_put() cannot free the eventpoll out from under eventpoll_release_file(); the orphaned epi is then cleaned up there. A successful pin also proves we are not racing eventpoll_release_file() on this epi, so drop the now-redundant re-check of epi->dying under f_lock. The cheap lockless READ_ONCE(epi->dying) fast-path bailout stays.
Title eventpoll: fix ep_remove struct eventpoll / struct file UAF
First Time appeared Linux
Linux linux Kernel
CPEs cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Vendors & Products Linux
Linux linux Kernel
References

Subscriptions

Linux Linux Kernel
cve-icon MITRE

Status: PUBLISHED

Assigner: Linux

Published:

Updated: 2026-05-30T12:13:45.594Z

Reserved: 2026-05-13T15:03:33.107Z

Link: CVE-2026-46242

cve-icon Vulnrichment

No data.

cve-icon NVD

Status : Received

Published: 2026-05-30T13:16:21.980

Modified: 2026-05-30T13:16:21.980

Link: CVE-2026-46242

cve-icon Redhat

No data.

cve-icon OpenCVE Enrichment

Updated: 2026-05-30T14:30:24Z

Weaknesses