CVE-2026-46242

Published May 30, 2026

Last updated 3 days ago

Overview

AI description

Automated description summarized from trusted sources.

CVE-2026-46242, dubbed "Bad Epoll," is a use-after-free vulnerability found within the Linux kernel's `eventpoll` (epoll) subsystem. The flaw arises from a race condition during the cleanup process of `epoll` file descriptors. Specifically, the `file->f_ep` pointer is cleared in the `ep_remove()` and `ep_remove_file()` functions while the `@file` pointer continues to be referenced within a critical section. This timing issue allows a concurrent `__fput()` operation to observe a transient NULL state for `f_ep`, causing it to bypass necessary cleanup routines and free the `struct eventpoll` object prematurely. Consequently, subsequent operations attempt to access freed memory, leading to memory corruption. The vulnerability affects Linux kernel versions 5.10 through 6.11, impacting a wide range of systems including enterprise servers, desktops, and Android devices.

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.
Source
416baaa9-dc9f-4396-8d5f-8c081fb06d67
NVD status
Modified
Products
linux_kernel

Risk scores

CVSS 3.1

Type
Secondary
Base score
7.8
Impact score
5.9
Exploitability score
1.8
Vector string
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Severity
HIGH

Weaknesses

nvd@nist.gov
CWE-416

Social media

Hype score
Not currently trending
  1. anthropic CVE-2026-46242. kernel CVEs cascade. patch the host, expect container escapes to follow within days. #Anthropic #CVE-2026-46242 https://t.co/hpOdrGCDAV

    @trerbbb

    1 Aug 2026

    45 Impressions

    1 Retweet

    1 Like

    0 Bookmarks

    0 Replies

    0 Quotes

  2. CVE-2026-46242. 0day Intel: A critical Bad Epoll vulnerability (CVE-2026-46242) allows local users to gain r

    @lyrie_ai

    22 Jul 2026

    41 Impressions

    0 Retweets

    0 Likes

    0 Bookmarks

    1 Reply

    0 Quotes

  3. 07:45 UTC: CVE-2026-46242 disclosed. A PoC/exploit has been discovered for vulnerability CVE-2026-46242 PT ID: PT-2026-45095 Vendor: Linux Product: Linux k

    @lyrie_ai

    22 Jul 2026

    67 Impressions

    0 Retweets

    0 Likes

    0 Bookmarks

    1 Reply

    0 Quotes

  4. Linuxカーネルのepollに、解放後利用(UAF)の脆弱性「Bad-Epoll」(CVE-2026-46242)が報告されています。epollは多数の接続や入出力の状態変化をまとめて監視する中核機能。2つの処理が同時に走ったときだけ成立す

    @MalwareBibleJP

    19 Jul 2026

    1365 Impressions

    2 Retweets

    12 Likes

    3 Bookmarks

    0 Replies

    0 Quotes

  5. What a day! (and it's not over yet..) - GhostLock (CVE-2026-43499) Local Root Exploit - Bad epoll (CVE-2026-46242) Local Root Exploit - cPanel File Manager security issue - WHMCS security update

    @georgetasioulis

    8 Jul 2026

    509 Impressions

    0 Retweets

    4 Likes

    1 Bookmark

    0 Replies

    0 Quotes

  6. Added 4 new LPE exploits to lpe-toolkit: - PEdit COW CVE-2026-46331 - DirtyClone CVE-2026-43503 - Bad Epoll CVE-2026-46242 - FUSE OOB CVE-2026-31694 https://t.co/BmdCcmBkWK

    @portbuster1337

    6 Jul 2026

    10226 Impressions

    48 Retweets

    211 Likes

    137 Bookmarks

    2 Replies

    1 Quote

  7. Linux-Kernel Bad Epoll CVE-2026-46242: Lokaler Nutzer erhält Root auf Kernel 6.4 und neuer Am 4. Juli 2026 wurde CVE-2026-46242 veröffentlicht, eine Use-after-free-Race-Co https://t.co/onahzNgWQO https://t.co/p0R4gM18Mh

    @schoenfelderED

    6 Jul 2026

    7 Impressions

    0 Retweets

    0 Likes

    0 Bookmarks

    0 Replies

    0 Quotes

  8. Bad Epoll (CVE-2026-46242) is a Linux kernel use-after-free flaw that lets unprivileged users gain root. Affects Linux 6.4+ and Android. For More: https://t.co/ciA4rj9abR #BadEpoll #CVE #LinuxKernel #PrivilegeEscalation #Android #InfoSec #CyberSecurity #LinuxSecurity https://t

    @redsecuretech

    4 Jul 2026

    45 Impressions

    0 Retweets

    0 Likes

    0 Bookmarks

    0 Replies

    0 Quotes

  9. A lot of offensive activities were identified targeting Linux Kernel (CVE-2026-46242) https://t.co/EsMCWe721V

    @vuldb

    31 May 2026

    59 Impressions

    0 Retweets

    0 Likes

    0 Bookmarks

    0 Replies

    0 Quotes

  10. There is a new vulnerability with elevated criticality in Linux Kernel (CVE-2026-46242) https://t.co/ZjftEUzzgM

    @vuldb

    30 May 2026

    24 Impressions

    0 Retweets

    0 Likes

    0 Bookmarks

    0 Replies

    0 Quotes

  11. CVE-2026-46242 Linux Kernel Eventpoll Use-After-Free via Concurrent File Descriptor Operations https://t.co/Md8jvYakK8

    @VulmonFeeds

    30 May 2026

    38 Impressions

    0 Retweets

    0 Likes

    0 Bookmarks

    0 Replies

    0 Quotes

Configurations

  1. In the Linux kernel, the following vulnerability has been resolved: cgroup: Avoid iteration of dying tasks with zero refcount The commit 260fbcb92bbea ("cgroup: Move dying_tasks cleanup from cgroup_task_release() to cgroup_task_free()") extended the lifetime of tasks on the dying_tasks list. The iterators have provision to go through dying_tasks because of dying threadgroup leaders or explicit CSS_TASK_ITER_WITH_DEAD, however, it was expected that such tasks can obtain a new reference (that is possible before cgroup_task_release()/put_task_struct_rcu_user()). The tasks after cgroup_task_release() and before cgroup_task_free() are subject to race when they may or may not have ->usage count > 0. The race window is between css_task_iter_next() invocations when css_set_lock is released and we may arrive at a new ->task_pos. The iterator should not attempt to resurrect tasks whose ->usage count dropped to zero. (When that happens, __put_task_struct_rcu_cb() is already imminent and the returned task_struct would could be used after free.) As for the fix, we cannot simply check the signal->live count of a task on the dying list because that won't distinguish regular zombies waiting to be reaped from RCU remnant tasks that are going to be free'd. Therefore add an extra check to rule out ->usage==0 tasks from any iteration. The repeat: loop in css_task_iter_advance() doesn't consider ->usage count, so add a new loop to css_task_iter_next() to skip de-used tasks on the dying_list. Rough illustration of the possible race R (reader of cgroup.procs) T (thread) L (group leader) --------------------------------- -------------------------------- -------------------------------- L exits, signal->live > 0 cgroup_task_dead(L) css_set_skip_task_iters() // skips only cset->tasks list_add_tail(&L->cg_list, &cset->dying_tasks) css_task_iter_next() take css_set_lock css_task_iter_advance() leader && signal->live != 0 => it->task_pos = &L->cg_list release css_set_lock T exits --signal->live == 0 cgroup_task_dead(T) // css_set_lock release_task(T) cgroup_task_release(T) release_task(L) // zap_leader cgroup_task_release(L) put_task_struct_rcu_user(L) ...RCU... put_task_struct(L) L->usage = 0 /* L still on dying_tasks */ ...RCU... __put_task_struct(L) css_task_iter_next() // another iteration take css_set_lock it->task_pos = &L->cg_list get_task_struct(L) => addition on 0 drop css_set_lock cgroup_task_free(L) css_set_skip_task_iters() // dying skip comes too late free_task(L) cgroup_procs_show() task_pid_vnr(L)•CVE-2026-98163