Skip to main content

Linux Kernel CVE-2026-31456

| EUVDEUVD-2026-24795 MEDIUM
Race Condition (CWE-362)
2026-04-22 416baaa9-dc9f-4396-8d5f-8c081fb06d67 GHSA-x569-m75g-6pr8
4.7
CVSS 3.1 · NVD
Share

Severity by source

NVD PRIMARY
4.7 MEDIUM
AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H
SUSE
MEDIUM
qualitative
Red Hat
5.5 MEDIUM
qualitative

Primary rating from NVD.

CVSS VectorNVD

CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H
Attack Vector
Local
Attack Complexity
High
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

Lifecycle Timeline

6
Analysis Generated
May 05, 2026 - 23:30 vuln.today
CVSS changed
May 05, 2026 - 21:22 NVD
4.7 (MEDIUM)
Patch released
Apr 23, 2026 - 16:17 nvd
Patch available
Patch available
Apr 22, 2026 - 16:02 EUVD
EUVD ID Assigned
Apr 22, 2026 - 14:22 euvd
EUVD-2026-24795
CVE Published
Apr 22, 2026 - 14:16 nvd
N/A

DescriptionCVE.org

In the Linux kernel, the following vulnerability has been resolved:

mm/pagewalk: fix race between concurrent split and refault

The splitting of a PUD entry in walk_pud_range() can race with a concurrent thread refaulting the PUD leaf entry causing it to try walking a PMD range that has disappeared.

An example and reproduction of this is to try reading numa_maps of a process while VFIO-PCI is setting up DMA (specifically the vfio_pin_pages_remote call) on a large BAR for that process.

This will trigger a kernel BUG: vfio-pci 0000:03:00.0: enabling device (0000 -> 0002) BUG: unable to handle page fault for address: ffffa23980000000 PGD 0 P4D 0 Oops: Oops: 0000 [#1] SMP NOPTI ... RIP: 0010:walk_pgd_range+0x3b5/0x7a0 Code: 8d 43 ff 48 89 44 24 28 4d 89 ce 4d 8d a7 00 00 20 00 48 8b 4c 24 28 49 81 e4 00 00 e0 ff 49 8d 44 24 ff 48 39 c8 4c 0f 43 e3 <49> f7 06 9f ff ff ff 75 3b 48 8b 44 24 20 48 8b 40 28 48 85 c0 74 RSP: 0018:ffffac23e1ecf808 EFLAGS: 00010287 RAX: 00007f44c01fffff RBX: 00007f4500000000 RCX: 00007f44ffffffff RDX: 0000000000000000 RSI: 000ffffffffff000 RDI: ffffffff93378fe0 RBP: ffffac23e1ecf918 R08: 0000000000000004 R09: ffffa23980000000 R10: 0000000000000020 R11: 0000000000000004 R12: 00007f44c0200000 R13: 00007f44c0000000 R14: ffffa23980000000 R15: 00007f44c0000000 FS: 00007fe884739580(0000) GS:ffff9b7d7a9c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffa23980000000 CR3: 000000c0650e2005 CR4: 0000000000770ef0 PKRU: 55555554 Call Trace: <TASK> __walk_page_range+0x195/0x1b0 walk_page_vma+0x62/0xc0 show_numa_map+0x12b/0x3b0 seq_read_iter+0x297/0x440 seq_read+0x11d/0x140 vfs_read+0xc2/0x340 ksys_read+0x5f/0xe0 do_syscall_64+0x68/0x130 ? get_page_from_freelist+0x5c2/0x17e0 ? mas_store_prealloc+0x17e/0x360 ? vma_set_page_prot+0x4c/0xa0 ? __alloc_pages_noprof+0x14e/0x2d0 ? __mod_memcg_lruvec_state+0x8d/0x140 ? __lruvec_stat_mod_folio+0x76/0xb0 ? __folio_mod_stat+0x26/0x80 ? do_anonymous_page+0x705/0x900 ? __handle_mm_fault+0xa8d/0x1000 ? __count_memcg_events+0x53/0xf0 ? handle_mm_fault+0xa5/0x360 ? do_user_addr_fault+0x342/0x640 ? arch_exit_to_user_mode_prepare.constprop.0+0x16/0xa0 ? irqentry_exit_to_user_mode+0x24/0x100 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7fe88464f47e Code: c0 e9 b6 fe ff ff 50 48 8d 3d be 07 0b 00 e8 69 01 02 00 66 0f 1f 84 00 00 00 00 00 64 8b 04 25 18 00 00 00 85 c0 75 14 0f 05 <48> 3d 00 f0 ff ff 77 5a c3 66 0f 1f 84 00 00 00 00 00 48 83 ec 28 RSP: 002b:00007ffe6cd9a9b8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007fe88464f47e RDX: 0000000000020000 RSI: 00007fe884543000 RDI: 0000000000000003 RBP: 00007fe884543000 R08: 00007fe884542010 R09: 0000000000000000 R10: fffffffffffffbc5 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000003 R14: 0000000000020000 R15: 0000000000020000 </TASK>

Fix this by validating the PUD entry in walk_pmd_range() using a stable snapshot (pudp_get()). If the PUD is not present or is a leaf, retry the walk via ACTION_AGAIN instead of descending further. This mirrors the retry logic in walk_pte_range(), which lets walk_pmd_range() retry if the PTE is not being got by pte_offset_map_lock().

AnalysisAI

A race condition in the Linux kernel's page table walking code (mm/pagewalk) allows local authenticated attackers to trigger a kernel panic (denial of service) by concurrent PUD splitting and refaulting operations. The vulnerability occurs when one thread is reading proc/[pid]/numa_maps while another thread (e.g., VFIO-PCI DMA setup) modifies the page table hierarchy, causing walk_pmd_range() to attempt walking a PMD range that no longer exists. The condition requires local access and a privileged operation (VFIO DMA pinning), but can reliably crash the kernel, affecting system availability.

Technical ContextAI

The vulnerability exists in the Linux kernel's page table walking infrastructure (mm/pagewalk.c), specifically in the interaction between walk_pud_range() and walk_pmd_range(). When a PUD (Page Upper Directory) entry is split into a leaf page by one thread while another thread is concurrently traversing the page table hierarchy, the second thread can encounter a stale PUD entry and attempt to dereference memory that no longer contains valid PMD (Page Middle Directory) tables. The root cause is a missing synchronization mechanism (CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization) between PUD splitting and PUD validation during page table walks. The fix implements a stable snapshot (pudp_get()) to detect when a PUD entry has become a leaf or disappeared, allowing the walk to retry via ACTION_AGAIN rather than accessing invalid memory. This mirrors existing retry logic in walk_pte_range() for similar races. Affected CPE ranges indicate the vulnerability spans multiple kernel versions from the 6.x and 7.0-rc series.

RemediationAI

Update the Linux kernel to version 6.18.21, 6.19.11, 7.0 or later, which include the fix implementing pudp_get() snapshot validation in walk_pmd_range(). For distributions with backported fixes, apply the patch from the vendor advisory (reference: https://git.kernel.org/stable/c/38ec58670a0c5fc1edabdeccd857e586b7b3f318). If immediate patching is not feasible, temporary mitigation includes disabling VFIO-PCI pass-through or avoiding concurrent numa_maps reads during VFIO DMA setup by serializing these operations (e.g., using a mutex in userspace). However, these workarounds reduce functionality and are not reliable against accidental concurrent access - patching is the only complete fix. The patch introduces minimal overhead (single stable snapshot read per PUD entry during page table walks) with no functional side effects.

Vendor StatusVendor

SUSE

Severity: Medium
Product Status
SUSE Linux Enterprise Desktop 15 SP7 Fixed
SUSE Linux Enterprise Desktop 15 SP7 Fixed
SUSE Linux Enterprise High Availability Extension 15 SP7 Fixed
SUSE Linux Enterprise High Availability Extension 15 SP7 Fixed
SUSE Linux Enterprise High Performance Computing 15 SP7 Fixed

Share

CVE-2026-31456 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy