CVE-2026-89986 Overview
CVE-2026-89986 is a Linux kernel vulnerability in the memory policy subsystem (mm/mempolicy). The flaw resides in alloc_pages_bulk_weighted_interleave(), which hardcodes GFP_KERNEL when allocating a temporary weights array. When invoked from atomic or RCU read-side contexts, this triggers a sleeping allocation and a might_alloc() splat. The issue was reported by syzbot after rhashtable_insert_slow() rehashed a table under rcu_read_lock() and invoked bucket_table_alloc() with GFP_ATOMIC | __GFP_NOWARN, which then reached the weighted interleave path via vmalloc.
Critical Impact
A local user whose task carries an MPOL_WEIGHTED_INTERLEAVE mempolicy can trigger a sleeping allocation inside an RCU read-side critical section, producing kernel warnings and risking scheduling or stability faults on affected systems.
Affected Products
- Linux kernel builds containing the weighted interleave mempolicy code path in mm/mempolicy.c
- Distributions shipping kernels prior to the fixes referenced in the upstream stable commits
- Systems configured with MPOL_WEIGHTED_INTERLEAVE NUMA memory policies
Discovery Timeline
- 2026-09-16 - CVE-2026-89986 published to the National Vulnerability Database
- 2026-09-16 - Last updated in NVD database
Technical Details for CVE-2026-89986
Vulnerability Analysis
The defect is a kernel-level context violation in the NUMA memory policy allocator. alloc_pages_bulk_weighted_interleave() allocates a temporary weights buffer using kmalloc(..., GFP_KERNEL). GFP_KERNEL permits the allocator to sleep, which is illegal inside atomic sections such as RCU read-side critical regions.
The reproducer path starts in rhashtable_insert_slow(). That function holds rcu_read_lock() while rehashing and then calls bucket_table_alloc(..., GFP_ATOMIC | __GFP_NOWARN). When the bucket table is large enough to route through vmalloc, __vmalloc_node_range_noprof() invokes vm_area_alloc_pages(), which in turn calls alloc_pages_bulk_mempolicy_noprof() with the caller's atomic flags. If the current task's mempolicy is MPOL_WEIGHTED_INTERLEAVE, control reaches the buggy helper, which ignores the caller-supplied flags and issues a sleeping allocation.
Root Cause
The root cause is a hardcoded GFP_KERNEL in a helper that must honor its caller's allocation constraints. The fix passes the caller-supplied gfp flags, masked with GFP_RECLAIM_MASK to strip page-allocator zone modifiers such as __GFP_HIGHMEM, into kmalloc(). Because the weights buffer is fully initialized immediately after allocation, kmalloc() without zeroing is sufficient. The corrective changes are captured in upstream commits 0ceda28, 2943f1f4, 540e583b, and bcb3d0c8.
Attack Vector
The attack vector is local. A user-space task sets MPOL_WEIGHTED_INTERLEAVE via the set_mempolicy() or mbind() system calls and then drives kernel code paths that perform bulk page allocations from atomic contexts, such as workloads that stress rhashtable rehashing. The result is a sleeping-in-atomic warning and potential secondary faults inside RCU critical sections.
No verified public exploit code is available. See the upstream stable commits linked above for the patch diffs.
Detection Methods for CVE-2026-89986
Indicators of Compromise
- Kernel log entries containing BUG: sleeping function called from invalid context referencing bucket_table_alloc or alloc_pages_bulk_weighted_interleave
- might_alloc() or might_sleep() splats emitted while rcu_read_lock() is held
- Unexpected soft lockups or scheduler warnings on NUMA hosts running weighted interleave policies
Detection Strategies
- Review dmesg and syslog aggregation for the sleeping function called from invalid context signature originating in mm/mempolicy.c
- Inventory workloads that set MPOL_WEIGHTED_INTERLEAVE through set_mempolicy() or numactl --weighted-interleave and correlate with kernel warnings
- Track kernel package versions across the fleet to identify hosts running builds prior to the fixed stable commits
Monitoring Recommendations
- Forward kernel ring buffer messages to a central log platform and alert on BUG: and WARNING: entries from memory management code
- Monitor NUMA-heavy hosts, including tiered-memory and CXL systems, where weighted interleave policies are commonly used
- Baseline rhashtable growth events in networking and namespace-heavy workloads that may trigger the vulnerable path
How to Mitigate CVE-2026-89986
Immediate Actions Required
- Apply the upstream stable kernel updates that incorporate commits 0ceda28, 2943f1f4, 540e583b, and bcb3d0c8
- Reboot affected hosts to load the patched kernel image
- Audit workloads for use of MPOL_WEIGHTED_INTERLEAVE and prioritize patching on systems where it is active
Patch Information
The fix modifies alloc_pages_bulk_weighted_interleave() in mm/mempolicy.c to propagate the caller-supplied gfp flags to kmalloc(), masked with GFP_RECLAIM_MASK. Refer to the stable tree commits 0ceda28, 2943f1f4, 540e583b, and bcb3d0c8 for the authoritative changes and distribution-specific backports.
Workarounds
- Avoid setting MPOL_WEIGHTED_INTERLEAVE on tasks that exercise kernel code paths performing bulk allocations from atomic contexts
- Replace weighted interleave with MPOL_INTERLEAVE or default policy on unpatched hosts as a temporary measure
- Restrict local user access on multi-tenant systems until patched kernels are deployed
# Verify current kernel version and check for the fix
uname -r
# Inspect mempolicy of a running process
cat /proc/<pid>/numa_maps | head
# Temporarily switch a workload away from weighted interleave
numactl --interleave=all <command>
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.