{"api_version":"1","generated_at":"2026-11-06T18:31:09+00:00","cve":"CVE-2026-99228","urls":{"html":"https://cve.report/CVE-2026-99228","api":"https://cve.report/api/cve/CVE-2026-99228.json","docs":"https://cve.report/api","cve_org":"https://www.cve.org/CVERecord?id=CVE-2026-99228","nvd":"https://nvd.nist.gov/vuln/detail/CVE-2026-99228"},"summary":{"title":"io_uring/io-wq: don't lose the signal that ends work","description":"In the Linux kernel, the following vulnerability has been resolved:\n\nio_uring/io-wq: don't lose the signal that ends work\n\nWhen a thread exits, only its tracked requests are cancelled. Then its\nio-wq is torn down. io_wq_exit_workers() signals every worker, to get it\nout of an interruptible sleep, and waits for all of them to exit. Before\nthey do, they go through the work that is left. Unbounded work is\ncancelled. Bounded work is run, as it is expected to end by itself.\n\nNot all of it does. An open has no file yet, so it counts as bounded, and\nthe open of a FIFO waits for the other end. That is what the signal is for.\nBut the workers are signalled once, and a worker that hasn't started the\nwork by then loses the signal:\n\n  io_wq_exit_workers()               io_worker_handle_work()\n    io_wq_worker_wake()\n      set TIF_NOTIFY_SIGNAL\n                                       io_assign_current_work()\n                                         io_run_task_work()\n                                           clear TIF_NOTIFY_SIGNAL\n                                       io_wq_submit_work()\n                                         fifo_open()\n                                           wait_for_partner()\n    wait_for_completion_timeout()\n\nThe thread never gets out of do_exit():\n\n  IORING_OP_OPENAT of a FIFO without a writer, IOSQE_ASYNC\n  exit of the thread that has submitted it\n\nhangs in more than 9 of 10 attempts (4 CPUs, KVM), until the process is\nkilled.\n\nSet TIF_NOTIFY_SIGNAL for bounded work that is started with IO_WQ_BIT_EXIT\nset. The bit is set before the workers are signalled, and it is tested\nafter the flag has been cleared, with clear_notify_signal() providing the\nbarrier. So either the flag stays, or the bit is seen.\n\nWork that is started while the io-wq exits is treated like work that is\nbeing run at that time: it isn't interrupted unless it waits\ninterruptibly.","state":"PUBLISHED","assigner":"Linux","published_at":"2026-11-02 16:17:47","updated_at":"2026-11-06 18:18:32"},"problem_types":[],"metrics":[],"references":[{"url":"https://git.kernel.org/stable/c/fdb771015c1e13677b57a4015f0c938748f13781","name":"https://git.kernel.org/stable/c/fdb771015c1e13677b57a4015f0c938748f13781","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://git.kernel.org/stable/c/62996803c1b5f18176de255db4c843021f2d19c8","name":"https://git.kernel.org/stable/c/62996803c1b5f18176de255db4c843021f2d19c8","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://git.kernel.org/stable/c/7df9a3b5eda51c512d3dd138e3b7daa525071757","name":"https://git.kernel.org/stable/c/7df9a3b5eda51c512d3dd138e3b7daa525071757","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://git.kernel.org/stable/c/7309fea05a3d66af9746843c43fef14c10b8141e","name":"https://git.kernel.org/stable/c/7309fea05a3d66af9746843c43fef14c10b8141e","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://git.kernel.org/stable/c/08c42055b8f9a5d29236d34ad4bce08828239fe1","name":"https://git.kernel.org/stable/c/08c42055b8f9a5d29236d34ad4bce08828239fe1","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://git.kernel.org/stable/c/63c103279a95e82280092f2f4232e91e8117a252","name":"https://git.kernel.org/stable/c/63c103279a95e82280092f2f4232e91e8117a252","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://git.kernel.org/stable/c/ddccc60f036b309430cf130d48aafed94ef7355a","name":"https://git.kernel.org/stable/c/ddccc60f036b309430cf130d48aafed94ef7355a","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-99228","name":"CVE Program record","refsource":"CVE.ORG","tags":["canonical"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-99228","name":"NVD vulnerability detail","refsource":"NVD","tags":["canonical","analysis"]}],"affected":[{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected afcc4015d1bf5659b8c722aff679e9b8c41ee156 ddccc60f036b309430cf130d48aafed94ef7355a git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected afcc4015d1bf5659b8c722aff679e9b8c41ee156 08c42055b8f9a5d29236d34ad4bce08828239fe1 git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected afcc4015d1bf5659b8c722aff679e9b8c41ee156 62996803c1b5f18176de255db4c843021f2d19c8 git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected afcc4015d1bf5659b8c722aff679e9b8c41ee156 7309fea05a3d66af9746843c43fef14c10b8141e git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected afcc4015d1bf5659b8c722aff679e9b8c41ee156 fdb771015c1e13677b57a4015f0c938748f13781 git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected afcc4015d1bf5659b8c722aff679e9b8c41ee156 7df9a3b5eda51c512d3dd138e3b7daa525071757 git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected afcc4015d1bf5659b8c722aff679e9b8c41ee156 63c103279a95e82280092f2f4232e91e8117a252 git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 5.12","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 5.12 semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 6.1.191 6.1.* semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 6.6.161 6.6.* semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 6.12.115 6.12.* semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 6.18.60 6.18.* semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 7.2.14 7.2.* semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 7.3.2 7.3.* semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 7.4-rc1 * original_commit_for_fix","platforms":[]}],"timeline":[],"solutions":[],"workarounds":[],"exploits":[],"credits":[],"nvd_cpes":[],"vendor_comments":[],"enrichments":{"kev":null,"epss":{"cve_year":"2026","cve_id":"99228","cve":"CVE-2026-99228","epss":"0.001570000","percentile":"0.048350000","score_date":"2026-11-03","updated_at":"2026-11-04 00:14:34"},"legacy_qids":[]},"source_records":{"cve_program":{"containers":{"cna":{"affected":[{"defaultStatus":"unaffected","product":"Linux","programFiles":["io_uring/io-wq.c"],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","vendor":"Linux","versions":[{"lessThan":"ddccc60f036b309430cf130d48aafed94ef7355a","status":"affected","version":"afcc4015d1bf5659b8c722aff679e9b8c41ee156","versionType":"git"},{"lessThan":"08c42055b8f9a5d29236d34ad4bce08828239fe1","status":"affected","version":"afcc4015d1bf5659b8c722aff679e9b8c41ee156","versionType":"git"},{"lessThan":"62996803c1b5f18176de255db4c843021f2d19c8","status":"affected","version":"afcc4015d1bf5659b8c722aff679e9b8c41ee156","versionType":"git"},{"lessThan":"7309fea05a3d66af9746843c43fef14c10b8141e","status":"affected","version":"afcc4015d1bf5659b8c722aff679e9b8c41ee156","versionType":"git"},{"lessThan":"fdb771015c1e13677b57a4015f0c938748f13781","status":"affected","version":"afcc4015d1bf5659b8c722aff679e9b8c41ee156","versionType":"git"},{"lessThan":"7df9a3b5eda51c512d3dd138e3b7daa525071757","status":"affected","version":"afcc4015d1bf5659b8c722aff679e9b8c41ee156","versionType":"git"},{"lessThan":"63c103279a95e82280092f2f4232e91e8117a252","status":"affected","version":"afcc4015d1bf5659b8c722aff679e9b8c41ee156","versionType":"git"}]},{"defaultStatus":"affected","product":"Linux","programFiles":["io_uring/io-wq.c"],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","vendor":"Linux","versions":[{"status":"affected","version":"5.12"},{"lessThan":"5.12","status":"unaffected","version":"0","versionType":"semver"},{"lessThanOrEqual":"6.1.*","status":"unaffected","version":"6.1.191","versionType":"semver"},{"lessThanOrEqual":"6.6.*","status":"unaffected","version":"6.6.161","versionType":"semver"},{"lessThanOrEqual":"6.12.*","status":"unaffected","version":"6.12.115","versionType":"semver"},{"lessThanOrEqual":"6.18.*","status":"unaffected","version":"6.18.60","versionType":"semver"},{"lessThanOrEqual":"7.2.*","status":"unaffected","version":"7.2.14","versionType":"semver"},{"lessThanOrEqual":"7.3.*","status":"unaffected","version":"7.3.2","versionType":"semver"},{"lessThanOrEqual":"*","status":"unaffected","version":"7.4-rc1","versionType":"original_commit_for_fix"}]}],"cpeApplicability":[{"nodes":[{"cpeMatch":[{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"6.1.191","versionStartIncluding":"5.12","vulnerable":true},{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"6.6.161","versionStartIncluding":"5.12","vulnerable":true},{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"6.12.115","versionStartIncluding":"5.12","vulnerable":true},{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"6.18.60","versionStartIncluding":"5.12","vulnerable":true},{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"7.2.14","versionStartIncluding":"5.12","vulnerable":true},{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"7.3.2","versionStartIncluding":"5.12","vulnerable":true},{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"7.4-rc1","versionStartIncluding":"5.12","vulnerable":true}],"negate":false,"operator":"OR"}]}],"descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\nio_uring/io-wq: don't lose the signal that ends work\n\nWhen a thread exits, only its tracked requests are cancelled. Then its\nio-wq is torn down. io_wq_exit_workers() signals every worker, to get it\nout of an interruptible sleep, and waits for all of them to exit. Before\nthey do, they go through the work that is left. Unbounded work is\ncancelled. Bounded work is run, as it is expected to end by itself.\n\nNot all of it does. An open has no file yet, so it counts as bounded, and\nthe open of a FIFO waits for the other end. That is what the signal is for.\nBut the workers are signalled once, and a worker that hasn't started the\nwork by then loses the signal:\n\n  io_wq_exit_workers()               io_worker_handle_work()\n    io_wq_worker_wake()\n      set TIF_NOTIFY_SIGNAL\n                                       io_assign_current_work()\n                                         io_run_task_work()\n                                           clear TIF_NOTIFY_SIGNAL\n                                       io_wq_submit_work()\n                                         fifo_open()\n                                           wait_for_partner()\n    wait_for_completion_timeout()\n\nThe thread never gets out of do_exit():\n\n  IORING_OP_OPENAT of a FIFO without a writer, IOSQE_ASYNC\n  exit of the thread that has submitted it\n\nhangs in more than 9 of 10 attempts (4 CPUs, KVM), until the process is\nkilled.\n\nSet TIF_NOTIFY_SIGNAL for bounded work that is started with IO_WQ_BIT_EXIT\nset. The bit is set before the workers are signalled, and it is tested\nafter the flag has been cleared, with clear_notify_signal() providing the\nbarrier. So either the flag stays, or the bit is seen.\n\nWork that is started while the io-wq exits is treated like work that is\nbeing run at that time: it isn't interrupted unless it waits\ninterruptibly."}],"providerMetadata":{"dateUpdated":"2026-11-06T17:15:09.971Z","orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","shortName":"Linux"},"references":[{"url":"https://git.kernel.org/stable/c/ddccc60f036b309430cf130d48aafed94ef7355a"},{"url":"https://git.kernel.org/stable/c/08c42055b8f9a5d29236d34ad4bce08828239fe1"},{"url":"https://git.kernel.org/stable/c/62996803c1b5f18176de255db4c843021f2d19c8"},{"url":"https://git.kernel.org/stable/c/7309fea05a3d66af9746843c43fef14c10b8141e"},{"url":"https://git.kernel.org/stable/c/fdb771015c1e13677b57a4015f0c938748f13781"},{"url":"https://git.kernel.org/stable/c/7df9a3b5eda51c512d3dd138e3b7daa525071757"},{"url":"https://git.kernel.org/stable/c/63c103279a95e82280092f2f4232e91e8117a252"}],"title":"io_uring/io-wq: don't lose the signal that ends work","x_generator":{"engine":"bippy-1.2.0"}}},"cveMetadata":{"assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","assignerShortName":"Linux","cveId":"CVE-2026-99228","datePublished":"2026-11-02T16:06:36.680Z","dateReserved":"2026-09-25T10:25:14.402Z","dateUpdated":"2026-11-06T17:15:09.971Z","state":"PUBLISHED"},"dataType":"CVE_RECORD","dataVersion":"5.2"},"nvd":{"publishedDate":"2026-11-02 16:17:47","lastModifiedDate":"2026-11-06 18:18:32","problem_types":[],"metrics":[],"configurations":[]},"legacy_mitre":{"record":{"CveYear":"2026","CveId":"99228","Ordinal":"1","Title":"io_uring/io-wq: don't lose the signal that ends work","CVE":"CVE-2026-99228","Year":"2026"},"notes":[{"CveYear":"2026","CveId":"99228","Ordinal":"1","NoteData":"In the Linux kernel, the following vulnerability has been resolved:\n\nio_uring/io-wq: don't lose the signal that ends work\n\nWhen a thread exits, only its tracked requests are cancelled. Then its\nio-wq is torn down. io_wq_exit_workers() signals every worker, to get it\nout of an interruptible sleep, and waits for all of them to exit. Before\nthey do, they go through the work that is left. Unbounded work is\ncancelled. Bounded work is run, as it is expected to end by itself.\n\nNot all of it does. An open has no file yet, so it counts as bounded, and\nthe open of a FIFO waits for the other end. That is what the signal is for.\nBut the workers are signalled once, and a worker that hasn't started the\nwork by then loses the signal:\n\n  io_wq_exit_workers()               io_worker_handle_work()\n    io_wq_worker_wake()\n      set TIF_NOTIFY_SIGNAL\n                                       io_assign_current_work()\n                                         io_run_task_work()\n                                           clear TIF_NOTIFY_SIGNAL\n                                       io_wq_submit_work()\n                                         fifo_open()\n                                           wait_for_partner()\n    wait_for_completion_timeout()\n\nThe thread never gets out of do_exit():\n\n  IORING_OP_OPENAT of a FIFO without a writer, IOSQE_ASYNC\n  exit of the thread that has submitted it\n\nhangs in more than 9 of 10 attempts (4 CPUs, KVM), until the process is\nkilled.\n\nSet TIF_NOTIFY_SIGNAL for bounded work that is started with IO_WQ_BIT_EXIT\nset. The bit is set before the workers are signalled, and it is tested\nafter the flag has been cleared, with clear_notify_signal() providing the\nbarrier. So either the flag stays, or the bit is seen.\n\nWork that is started while the io-wq exits is treated like work that is\nbeing run at that time: it isn't interrupted unless it waits\ninterruptibly.","Type":"Description","Title":"io_uring/io-wq: don't lose the signal that ends work"}]}}}