CVE-2021-3491 Overview
CVE-2021-3491 is a heap overflow vulnerability in the Linux kernel io_uring subsystem. The PROVIDE_BUFFERS operation failed to enforce the MAX_RW_COUNT limit, which allowed negative length values to propagate into mem_rw when reading /proc/<PID>/mem. A local attacker can use this primitive to corrupt kernel heap memory and achieve arbitrary code execution in kernel context. The flaw was introduced in commit ddf0322db79c (io_uring: add IORING_OP_PROVIDE_BUFFERS) in v5.7-rc1 and fixed in commit d1f82808877b in v5.13-rc1, with backports to v5.12.4, v5.11.21, and v5.10.37.
Critical Impact
A local, low-privileged attacker can trigger a kernel heap overflow leading to arbitrary code execution and full system compromise.
Affected Products
- Linux Kernel versions v5.7-rc1 through v5.13-rc1 (before commit d1f82808877b)
- Linux Kernel stable branches prior to v5.10.37, v5.11.21, and v5.12.4
- Canonical Ubuntu Linux 20.04 LTS, 20.10, and 21.04
Discovery Timeline
- 2021-05-11 - Vulnerability disclosed on the OpenWall oss-security mailing list
- 2021-06-04 - CVE-2021-3491 published to NVD
- 2024-11-21 - Last updated in NVD database
Technical Details for CVE-2021-3491
Vulnerability Analysis
The io_uring subsystem provides an asynchronous I/O interface that lets userspace submit operations via shared ring buffers. One supported operation, IORING_OP_PROVIDE_BUFFERS, registers pre-allocated buffers the kernel can later use for reads and other operations. The handler accepted a user-controlled length without truncating it against the MAX_RW_COUNT limit applied elsewhere in the kernel I/O path.
When the registered buffer is subsequently consumed by a read against /proc/<PID>/mem, the mem_rw function receives the unchecked length. The length is interpreted as a signed integer, so values exceeding MAX_RW_COUNT become negative when cast. This signedness confusion combined with the missing bounds check results in writes far outside the allocated buffer.
The out-of-bounds write corrupts adjacent kernel heap objects, enabling local privilege escalation [CWE-787] and incorrect resource sizing [CWE-131]. Successful exploitation grants ring 0 code execution.
Root Cause
The io_provide_buffers handler did not validate or truncate the per-buffer length supplied through the submission queue entry. Other kernel read and write paths sanitize lengths against MAX_RW_COUNT, but this enforcement was missing in the io_uring provide-buffers path. The fix in commit d1f82808877b truncates lengths larger than MAX_RW_COUNT before storing them in the buffer descriptor.
Attack Vector
Exploitation requires local access and the ability to invoke io_uring system calls, which any unprivileged user can do on a default configuration. The attacker submits a PROVIDE_BUFFERS operation specifying an oversized length, opens /proc/self/mem, and issues a read that consumes the registered buffer. The kernel performs an out-of-bounds copy into adjacent heap memory. Reliable exploitation typically grooms the SLUB allocator to place a target object next to the overflowed buffer. Refer to the OpenWall OSS-Security Discussion and Zero Day Initiative Advisory ZDI-21-589 for additional technical detail.
Detection Methods for CVE-2021-3491
Indicators of Compromise
- Unexpected kernel oops, panic, or BUG: KASAN messages referencing mem_rw, io_uring, or SLUB heap corruption in /var/log/kern.log or dmesg output.
- Unprivileged processes invoking io_uring_setup, io_uring_register, and reads against /proc/<PID>/mem in close succession.
- Sudden privilege transitions where an unprivileged user gains UID 0 without a corresponding sudo, su, or SUID execution audit record.
Detection Strategies
- Enable Linux audit rules for the io_uring_setup, io_uring_enter, and io_uring_register syscalls, then alert on calls from non-allowlisted binaries.
- Monitor process-level access to /proc/*/mem originating from processes that also hold active io_uring instances.
- Deploy eBPF or kernel-level telemetry to track abnormal sequences of PROVIDE_BUFFERS submissions followed by /proc/<PID>/mem reads.
Monitoring Recommendations
- Centralize kernel logs and alert on kernel crash signatures involving io_uring or mem_rw symbols.
- Track installed kernel versions across the fleet and flag hosts running kernels between v5.7-rc1 and the patched stable releases.
- Correlate process-execution telemetry with subsequent privilege escalations to surface exploitation attempts.
How to Mitigate CVE-2021-3491
Immediate Actions Required
- Update the Linux kernel to v5.10.37, v5.11.21, v5.12.4, or v5.13-rc1 or later, which include commit d1f82808877b.
- Apply distribution patches such as Ubuntu Security Notice USN-4949-1 and Ubuntu Security Notice USN-4950-1 and reboot affected hosts.
- Inventory all multi-tenant systems, container hosts, and developer workstations running kernels in the vulnerable range and prioritize them for patching.
Patch Information
The upstream fix is Linux Kernel commit d1f82808877b, which truncates lengths larger than MAX_RW_COUNT in the io_uring provide-buffers path. Vendor advisories include the NetApp Security Advisory NTAP-20210716-0004 and the Ubuntu USN notices above.
Workarounds
- Restrict access to the io_uring subsystem by setting the kernel.io_uring_disabled sysctl where supported, or by blocking the io_uring_setup syscall via seccomp profiles for untrusted workloads.
- Apply a seccomp-bpf filter to container runtimes (Docker, containerd, Kubernetes) that denies io_uring syscalls until kernels are patched.
- Limit local shell access on multi-user systems and remove unnecessary local accounts to reduce the attack surface.
# Configuration example: disable io_uring via sysctl on supported kernels
sudo sysctl -w kernel.io_uring_disabled=2
echo 'kernel.io_uring_disabled=2' | sudo tee /etc/sysctl.d/99-disable-iouring.conf
# Verify kernel version contains the fix
uname -r
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


