HIGH Introduced in 6.15
io_uring FolioShift Overflow
CVE-2026-80810
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
01Description
In the Linux kernel, the following vulnerability has been resolved: io_uring/rsrc: fix folio size overflow in io_vec_fill_bvec() io_vec_fill_bvec() computes the folio size with a plain int 1: unsigned long folio_size = 1 << imu->folio_shift; imu->folio_shift is unsigned int and comes from folio_shift() of the folio backing the registered buffer, so it can be 32 or more on a 64 bit kernel. Shifting int 1 that far is undefined, and on x86 and arm64 the count is taken modulo 32, so a shift of 34 yields 4 rather than 16G. Every other folio_shift shift in this file already uses 1UL. The result is that the segment estimate and the fill loop disagree. io_estimate_bvec_size() sizes the bvec array with the real shift: max_segs += (iov[i].iov_len >> shift) + 2; so a 1M iovec on a 16G folio is charged 2 segments, while io_vec_fill_bvec() then walks the same iovec in folio_size chunks of 4 bytes and writes res_bvec[bvec_idx] a quarter of a million times, past the end of the array it was given. src_bvec is advanced once per iteration as well, so imu->bvec is read past its end at the same time. validate_fixed_range() only checks that the range is inside the registered buffer and does not bound the segment count. Reaching it needs a folio with a shift of at least 32, which means a gigantic hugetlb page: 16G on arm64 with 64K pages, where CONT_PMD_SHIFT is 34 and hugetlb_add_hstate(CONT_PMD_SHIFT - PAGE_SHIFT) registers that size, and likewise on powerpc. x86_64 tops out at 1G, so a shift of 30, which still fits in int and is unaffected. Use 1UL, as the rest of the file does.
02KernelScan AI Analysis
Risk summary
A local unprivileged user on arm64 or powerpc systems with gigantic hugetlb pages configured can trigger a massive out-of-bounds write in the kernel's io_uring registered buffer import path, corrupting kernel heap memory. The resulting memory corruption can lead to kernel code execution, privilege escalation, or a system crash. The attack requires a very specific platform and memory configuration, limiting the number of affected deployments.
Vulnerability analysis
When io_uring imports a vectored registered buffer backed by a gigantic hugetlb page, the kernel miscalculates the memory page size because it shifts a small integer that overflows on very large pages. On affected systems, the overflow makes the loop think each piece is only a few bytes long, so it writes far past the end of its internal segment array while also reading beyond the registered buffer's tracking data. The correction widens the constant to the proper integer size so the loop uses the true page size. Only arm64 and powerpc systems configured with gigantic huge pages are affected; x86_64 is not. Any local process that can use io_uring can trigger the flaw.
Lifecycle
03Fix Versions
| Branch | Introduced | Fixed in | Patch commit |
|---|---|---|---|
| 6.18 | 6.15 | 6.18.47 | 45c945107e00 |
| 7.1 | 6.15 | 7.1.11 | 6b308c37fbeb |
| 7.2 | 6.15 | 7.2.1 | 3267d7c8ba51 |
| mainline | 6.15 | 7.3 | 3f3a6a16bbe8 |