CVE-2026-43121

io_uring/zcrx: fix user_ref race between scrub and refill paths

Published May 6, 2026 CVSS 3.1 · 4.7 Medium EPSS < 1% KEV · Not listed
Description
In the Linux kernel, the following vulnerability has been resolved:

io_uring/zcrx: fix user_ref race between scrub and refill paths

The io_zcrx_put_niov_uref() function uses a non-atomic
check-then-decrement pattern (atomic_read followed by separate
atomic_dec) to manipulate user_refs. This is serialized against other
callers by rq_lock, but io_zcrx_scrub() modifies the same counter with
atomic_xchg() WITHOUT holding rq_lock.

On SMP systems, the following race exists:

CPU0 (refill, holds rq_lock) CPU1 (scrub, no rq_lock)
put_niov_uref:
atomic_read(uref) - 1
// window opens
atomic_xchg(uref, 0) - 1
return_niov_freelist(niov) [PUSH #1]
// window closes
atomic_dec(uref) - wraps to -1
returns true
return_niov(niov)
return_niov_freelist(niov) [PUSH #2: DOUBLE-FREE]

The same niov is pushed to the freelist twice, causing free_count to
exceed nr_iovs. Subsequent freelist pushes then perform an out-of-bounds
write (a u32 value) past the kvmalloc'd freelist array into the adjacent
slab object.

Fix this by replacing the non-atomic read-then-dec in
io_zcrx_put_niov_uref() with an atomic_try_cmpxchg loop that atomically
tests and decrements user_refs. This makes the operation safe against
concurrent atomic_xchg from scrub without requiring scrub to acquire
rq_lock.

[pavel: removed a warning and a comment]

Analysis

AI-generated

Technical impact

A race condition in the Linux kernel’s io_uring zcrx subsystem allows concurrent execution of the scrub and refill paths. The bug causes a reference counter to underflow to –1 and results in a double‑free of an internal buffer. Subsequent freelist pushes write beyond the bounds of the allocated array, corrupting adjacent slab objects in kernel memory. Kernel memory corruption of this nature can enable arbitrary code execution at kernel privilege level, thereby providing the potential for privilege escalation.

Affected Systems

All Linux kernel releases that contain the io_uring zcrx implementation and have not yet incorporated the commit fixing the race. No specific version numbers are listed, so any kernel prior to the fix is considered vulnerable.

Risk and Exploitability

The CVSS score of 4.7 indicates moderate severity. The EPSS score of < 1 % suggests a very low probability of exploitation at this time. The vulnerability is not listed in CISA’s KEV catalog. Because the flaw results in a kernel memory corruption that could be leveraged for code execution, the risk remains significant for systems that support io_uring and do not employ additional hardening such as KASLR, SELinux, or lockdown features.

Remediation

No solution or workaround provided in the CVE record.

OpenCVE Recommended Actions

  • Apply the latest kernel update that incorporates the commit patches the io_uring zcrx race condition
  • If a kernel update cannot be applied immediately, disable or restrict use of io_uring to prevent the vulnerable code paths from being exercised
  • If the kernel remains unpatched, monitor system logs for unusual memory corruption events to detect exploitation attempts

Generated by OpenCVE AI on May 13, 2026 at 01:05 UTC.

Tracking

Sign in to view the affected projects.

Advisories

No advisories available
History
Type Values Removed Values Added
Weaknesses CWE-362
Metrics cvssV3_1

{'score': 4.7, 'vector': 'CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H'}

Type Values Removed Values Added
Weaknesses CWE-125
CWE-362
CWE-415
Type Values Removed Values Added
Weaknesses CWE-125
CWE-362
CWE-415
Type Values Removed Values Added
Description In the Linux kernel, the following vulnerability has been resolved: io_uring/zcrx: fix user_ref race between scrub and refill paths The io_zcrx_put_niov_uref() function uses a non-atomic check-then-decrement pattern (atomic_read followed by separate atomic_dec) to manipulate user_refs. This is serialized against other callers by rq_lock, but io_zcrx_scrub() modifies the same counter with atomic_xchg() WITHOUT holding rq_lock. On SMP systems, the following race exists: CPU0 (refill, holds rq_lock) CPU1 (scrub, no rq_lock) put_niov_uref: atomic_read(uref) - 1 // window opens atomic_xchg(uref, 0) - 1 return_niov_freelist(niov) [PUSH #1] // window closes atomic_dec(uref) - wraps to -1 returns true return_niov(niov) return_niov_freelist(niov) [PUSH #2: DOUBLE-FREE] The same niov is pushed to the freelist twice, causing free_count to exceed nr_iovs. Subsequent freelist pushes then perform an out-of-bounds write (a u32 value) past the kvmalloc'd freelist array into the adjacent slab object. Fix this by replacing the non-atomic read-then-dec in io_zcrx_put_niov_uref() with an atomic_try_cmpxchg loop that atomically tests and decrements user_refs. This makes the operation safe against concurrent atomic_xchg from scrub without requiring scrub to acquire rq_lock. [pavel: removed a warning and a comment]
Title io_uring/zcrx: fix user_ref race between scrub and refill paths
First Time appeared Linux
Linux linux Kernel
CPEs cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Vendors & Products Linux
Linux linux Kernel
References
Weaknesses
  • CWE-362

    Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')

  • CWE-366

    Race Condition within a Thread

Sources

Status
PUBLISHED
Assigner
Linux
Published
Updated
May 11, 2026, 10:18 PM
Reserved
May 1, 2026, 2:12 PM
Status
Analyzed
Published
May 6, 2026, 12:16 PM
Modified
Nov 11, 2026, 9:10 PM
Severity
Public date
May 6, 2026, 12:00 AM