CVE-2026-31456 Overview
CVE-2026-31456 is a race condition in the Linux kernel's memory management page walking code. The flaw exists in walk_pud_range() where splitting a Page Upper Directory (PUD) entry can race with a concurrent thread refaulting the PUD leaf entry. The race causes the walker to descend into a Page Middle Directory (PMD) range that has already disappeared, triggering an unhandled page fault and kernel crash.
The vulnerability is reproducible by reading numa_maps of a process while VFIO-PCI sets up Direct Memory Access (DMA) via vfio_pin_pages_remote on a large Base Address Register (BAR). The issue is tracked under [CWE-362] concurrent execution using shared resource with improper synchronization.
Critical Impact
Local low-privileged users can trigger a kernel BUG and denial of service by inducing the race between page table splits and refaults.
Affected Products
- Linux Kernel (mainline) prior to the fix commits
- Linux Kernel 7.0-rc1 through 7.0-rc5
- Distributions shipping kernels with the mm/pagewalk PUD splitting logic
Discovery Timeline
- 2026-04-22 - CVE-2026-31456 published to the National Vulnerability Database (NVD)
- 2026-05-05 - Last updated in NVD database
Technical Details for CVE-2026-31456
Vulnerability Analysis
The vulnerability resides in the kernel's generic page table walker walk_pgd_range / walk_pud_range / walk_pmd_range call chain. When a walker encounters a PUD leaf entry, it may attempt to split that entry into a PMD range for finer-grained traversal. A concurrent thread can refault the same address, removing or reinstalling the PUD leaf while the walker still holds a stale view.
When the walker subsequently calls into walk_pmd_range(), it dereferences a PMD pointer derived from a PUD entry that no longer maps the expected range. The result is a page fault on a kernel address such as ffffa23980000000, captured in the reported oops at walk_pgd_range+0x3b5/0x7a0, with the call originating from show_numa_map through seq_read and the read syscall path.
Root Cause
The root cause is the absence of a stable snapshot of the PUD entry between the split decision and the descent into the PMD range. walk_pud_range() reads the PUD once, then proceeds without re-validating that the entry remains a non-leaf, present PMD pointer. Concurrent allocators such as vfio_pin_pages_remote modify the PUD asynchronously, breaking the walker's assumption that the descent target is still valid.
Attack Vector
A local user with permission to read /proc/<pid>/numa_maps for a process whose address space is concurrently mutated by another subsystem can trigger the crash. The reproducer pairs a reader of numa_maps with a VFIO-PCI workload that performs DMA pinning on a large BAR mapping. The attack vector is local, attack complexity is high because it requires precise timing between the two threads, and the impact is limited to availability — the system panics or experiences a kernel oops with no confidentiality or integrity loss.
The upstream fix validates the PUD entry inside walk_pmd_range() using a stable snapshot taken via pudp_get(). If the snapshot shows the PUD is not present or is a leaf, the walker returns ACTION_AGAIN to retry the walk rather than descending into a stale PMD range. This mirrors the retry pattern already used in walk_pte_range() when pte_offset_map_lock() fails to obtain the PTE.
Detection Methods for CVE-2026-31456
Indicators of Compromise
- Kernel oops messages referencing walk_pgd_range, walk_pud_range, or walk_pmd_range in the call trace
- Page fault entries with CR2 pointing to a kernel virtual address while executing show_numa_map or seq_read_iter
- Repeated crashes correlated with processes opening /proc/<pid>/numa_maps while VFIO-PCI devices are initializing
Detection Strategies
- Collect kernel dmesg and /var/log/kern.log output and alert on BUG: unable to handle page fault entries that include walk_pud_range or walk_pmd_range frames
- Audit workloads that combine NUMA inspection tooling with VFIO-PCI passthrough — common in virtualization and GPU/accelerator hosts
- Monitor for unexpected reboots or kdump captures on kernels matching the affected version range
Monitoring Recommendations
- Forward kernel logs to a centralized logging or SIEM platform and create an alert for the specific walk_pgd_range+0x3b5 signature
- Track /proc/sys/kernel/tainted state changes after suspicious user activity reading numa_maps
- Correlate VFIO device binding events (vfio-pci 0000:xx:xx.x: enabling device) with subsequent kernel oops events
How to Mitigate CVE-2026-31456
Immediate Actions Required
- Apply the upstream stable kernel patches referenced below and reboot affected hosts
- Inventory hosts running Linux 7.0-rc1 through 7.0-rc5 and any distribution kernel that backported the pagewalk PUD-splitting logic without the fix
- Restrict local access on systems using VFIO-PCI passthrough until patched, since the race requires a concurrent local reader
Patch Information
The fix is contained in three upstream commits that introduce the stable pudp_get() snapshot and ACTION_AGAIN retry logic in walk_pmd_range():
Distribution maintainers should pull these commits into their stable trees and rebuild kernel packages. Verify the patched kernel boots cleanly under the original reproducer: concurrent numa_maps reads against a VFIO-PCI workload pinning a large BAR.
Workarounds
- Remove read access to /proc/<pid>/numa_maps for untrusted local users where feasible by tightening process ownership and hidepid mount options on /proc
- Avoid running NUMA inspection tools such as numactl --show or cat /proc/<pid>/numa_maps against processes that are concurrently performing VFIO DMA setup
- Disable VFIO-PCI passthrough on hosts that do not require device assignment until the patched kernel is deployed
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

