{"id":"CVE-2026-99231","kind":"vulnerability","aliases":["CVE-2026-99231"],"related":[],"title":"Linux kernel: io_uring waitid race lets a freed request be reused and corrupted","description":"In the Linux kernel, the following vulnerability has been resolved:\n\nio_uring/waitid: own the request before clearing ->head\n\nio_waitid_remove_wq() only takes the wait queue lock if ->head is set.\nio_waitid_wait() clears ->head first thing, before it tries to become the\nowner of the request by bumping ->refs. If somebody else owns the request\nat that point, nothing keeps it from completing the request while the\nwake up handler is still going to touch it:\n\nCPU0 (io_waitid_wait)                 CPU1 (io_waitid, holds a ref)\nlist_del_init(&wait->entry)\nsmp_store_release(&iw->head, NULL)\n                                      __do_wait() finds another child\n                                      io_waitid_remove_wq()\n                                        // ->head == NULL, no locking\n                                      io_waitid_finish(), IOU_COMPLETE\n                                      // request freed and reused\natomic_fetch_inc(&iw->refs)\n\nThe same goes for __io_waitid_cancel() if it claims the request in that\nwindow. ->refs is part of the per opcode data of the request, so this\nincrements whatever the next user of the request keeps there. If that\nhappens to be zero, the handler concludes that it owns the request, and\nqueues io_waitid_cb() for it. With the window held open by a delay, and\nthe request reused for a receive that is waiting for data:\n\n  BUG: KASAN: slab-use-after-free in __wake_up_common+0x1ca/0x1f0\n   __wake_up_sync_key+0x36/0x50\n   sock_def_readable+0xf1/0x420\n   unix_stream_sendmsg+0x60b/0x1110\n  Allocated by task 87:\n   io_arm_apoll+0x1ed/0x940\n  Freed by task 87:\n   __io_submit_flush_completions+0x118d/0x1a10\n   tctx_task_work_run+0x327/0x950\n\nOnly clear ->head once the handler owns the request. If it doesn't, the\nowner finds ->head set and has to wait for the lock, which is held by the\ncaller of the handler. Deleting the already deleted entry again is\nharmless.","summary":"A race in the Linux kernel's io_uring waitid handling can complete a request while its wake-up handler still touches it, leaving a use-after-free. The sources describe the consequence as a KASAN-reported slab use-after-free reachable through socket wake-up, and the sources do not state what an attacker can gain beyond that.","severity":"high","cvss":7.8,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["io-uring","kernel","linux","local","runtime"],"not_affected_if":["io-uring-disabled"],"how_to_check":"- Run uname -r and compare against your distro's kernel security tracker for CVE-2026-99231; upstream fixed versions are not yet published in the sources.\n- Run sysctl kernel.io_uring_disabled: 0 = enabled for all, 1 = restricted to privileged/group, 2 = disabled (on kernels that have the sysctl).\n- Check whether the patched io_uring/waitid.c contains the 'pairs with the smp_load_acquire() in io_waitid_remove_wq()' comment.","fix":"Upstream patch 'io_uring/waitid: own the request before clearing ->head' only clears ->head after the handler owns the request. Fixed kernel versions unknown; take your distro's kernel update once it lists CVE-2026-99231.","status":"open","published_at":"2026-11-02T16:17:48+00:00","first_seen_at":"2026-11-02T16:24:06+00:00","triaged_at":"2026-11-02T16:26:36+00:00","updated_at":"2026-11-02T16:29:40+00:00","category":"runtime","confidence":0.6,"triage":{"at":"2026-11-02T16:26:36Z","model":"claude-haiku-5-5","output":{"fix":"unknown","reach":"local","title":"Linux kernel: io_uring waitid race lets a freed request be reused and corrupted","impact":"high","summary":"A race in the Linux kernel's io_uring waitid handling can complete a request while its wake-up handler still touches it, leaving a use-after-free. The sources describe the consequence as a KASAN-reported slab use-after-free reachable through socket wake-up, and the sources do not state what an attacker can gain beyond that.","audience":"businesses","category":"runtime","nicknames":[],"who_cares":["linux","kernel","io-uring"],"confidence":0.5,"fix_status":"unknown","needs_auth":"unknown","worst_case":"memory corruption in the kernel, possibly code execution, per sources unknown","analyst_note":"Find the affected and fixed kernel version ranges and whether io_uring is reachable by unprivileged users, from the NVD entry and the upstream kernel commit.","how_to_check":"- Check the running kernel with `uname -r` and compare it against the fixed kernel versions named in the advisory, which the sources do not list.\n- Check whether io_uring is enabled on the host, for example with `sysctl kernel.io_uring_disabled`; the sources do not say whether this is the default.\n- unknown","plain_action":"","needs_analyst":true,"not_affected_if":["io-uring-disabled"],"who_is_affected":"The sources describe the flaw in the Linux kernel's io_uring waitid path, which is reached by applications that submit waitid operations through io_uring. The sources do not say which kernel versions are affected, whether io_uring is enabled by default, or whether any unprivileged user can trigger the race. unknown","user_interaction":"no","needs_special_setup":"unknown","severity_if_unknown":"unknown"},"cost_usd":0.000784,"input_tokens":4739,"output_tokens":621,"severity_before":"high"},"analyst_status":"done","analyst_note":"Find the affected and fixed kernel version ranges and whether io_uring is reachable by unprivileged users, from the NVD entry and the upstream kernel commit.","search":"'+0':308C,314C,319C,324C,333C,343C,349C '-2026':16A,19A '-99231':17A,20A '87':329C,338C 'alloc':326C 'alreadi':387C 'anoth':194C 'apol':332C 'arm':331C 'atom':213C 'attack':87B 'becom':134C 'beyond':90B 'bug':297C 'bump':141C 'caller':381C 'cancel':224C 'cb':274C 'child':195C 'claim':227C 'clear':107C,126C,352C 'common':307C 'complet':40B,156C,208C,342C 'conclud':264C 'consequ':62B 'corrupt':14A 'cpu0':170C 'cpu1':174C 'cve':15A,18A 'data':240C,296C 'def':317C 'del':181C 'delay':284C 'delet':385C,388C 'describ':60B 'doesn':362C 'els':145C 'entri':184C,389C 'fetch':214C 'find':193C,366C 'finish':206C 'first':128C 'flush':341C 'follow':96C 'free':57B,72B,303C 'freed':9A,210C,335C 'gain':89B 'go':166C 'goe':220C 'handl':38B 'handler':48B,163C,263C,356C,384C 'happen':258C 'harmless':392C 'head':108C,120C,127C,189C,200C,353C,367C 'held':280C,378C 'hold':177C 'inc':215C 'increment':246C 'init':182C 'io':3A,22B,35B,101C,109C,123C,171C,175C,196C,204C,222C,272C,330C,339C 'io-ur':21B 'iou':207C 'iw':188C,216C 'kasan':66B,298C 'kasan-report':65B 'keep':153C,254C 'kernel':2A,24B,33B,94C 'key':313C 'leav':52B 'let':7A 'linux':1A,25B,32B,93C 'list':180C 'local':26B 'lock':118C,203C,375C 'next':249C 'noth':152C 'null':190C,201C 'opcod':239C 'open':281C 'own':146C,267C,357C 'owner':136C,365C 'part':235C 'per':238C 'point':151C 'queue':117C,271C 'race':6A,29B 'reachabl':73B 'readabl':318C 'receiv':291C 'ref':142C,179C,217C,233C 'releas':187C 'remov':111C,198C 'report':67B 'request':10A,42B,105C,139C,148C,158C,209C,229C,243C,253C,269C,287C,359C 'resolv':100C 'reus':12A,212C,288C 'run':348C 'runtim':27B 'sendmsg':323C 'set':122C,368C 'slab':68B,300C 'slab-use-after-fre':299C 'smp':185C 'sock':316C 'socket':75B 'somebodi':144C 'sourc':59B,81B 'state':84B 'still':49B,165C 'store':186C 'stream':322C 'submit':340C 'sync':312C 'take':114C 'task':328C,337C,346C 'tctx':345C 'thing':129C 'touch':50B,168C 'tri':132C 'unix':321C 'ure':4A,23B,36B 'uring/waitid':102C 'use':55B,70B,301C 'use-after-fre':54B,69B 'user':250C 'vulner':97C 'wait':116C,125C,173C,183C,192C,294C,372C 'waitid':5A,37B,110C,124C,172C,176C,197C,205C,223C,273C 'wake':46B,77B,161C,305C,310C 'wake-up':45B,76B 'whatev':247C 'window':232C,279C 'work':347C 'wq':112C,199C 'x118d/0x1a10':344C 'x1ca/0x1f0':309C 'x1ed/0x940':334C 'x327/0x950':350C 'x36/0x50':315C 'x60b/0x1110':325C 'xf1/0x420':320C 'zero':261C","nicknames":[],"mitigations":[],"who_affected":"Linux systems whose kernel has io_uring with the IORING_OP_WAITID opcode, where local code can submit waitid requests through io_uring. The bug was introduced by upstream commit ab673c1bcaf2; which released kernel versions contain it is not stated in the sources. Hosts with io_uring disabled (kernel.io_uring_disabled sysctl) or no untrusted local code can deprioritize it. The sources do not say whether unprivileged users can reach it.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"unknown","audience":"businesses","plain_action":null,"pkeys":[],"ptokens":[],"labels":["high","iouring","kernel","linux","local","runtime"],"first_public_at":"2026-11-02T16:17:48+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","cvss_by":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-99231","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-99231","severity":null,"published_at":"2026-11-02T16:17:48+00:00","modified_at":"2026-11-02T16:17:48+00:00","first_seen_at":"2026-11-02T16:24:06+00:00","fetched_at":"2026-11-02T16:24:06+00:00","note":null},{"source":"analyst","external_id":"CVE-2026-99231:1394","url":null,"severity":null,"published_at":"2026-11-02T16:29:40+00:00","modified_at":"2026-11-02T16:29:40+00:00","first_seen_at":"2026-11-02T16:29:40+00:00","fetched_at":"2026-11-02T16:29:40+00:00","note":"Read upstream patch posting (Josef Bacik, 2026-10-15, patch 01/43 to io-uring list; Fixes: ab673c1bcaf2). No merged commit hash, stable release or fixed kernel version found; NVD/cve.org pages carry only the kernel.org text. Nothing marked verified (patch posting, not vendor advisory). Unprivileged reachability not stated in sources; CVSS vector is local/low-priv."}],"documents":[{"id":52868,"url":"https://lore.gnuweeb.org/io-uring/20261015-b4-io-uring-fixes-v1-1-c1556f5d7bf5@toxicpanda.com/","title":"[PATCH 01/43] io_uring/waitid: own the request before clearing ->head (Josef Bacik, 2026-10-15)","kind":"issue","source":"analyst","publisher":null,"text":null,"published_at":null,"relation":"fix","confidence":null,"note":null},{"id":52869,"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-99231","title":"NVD CVE-2026-99231","kind":"advisory","source":"analyst","publisher":null,"text":null,"published_at":null,"relation":"describes","confidence":null,"note":null}],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}