From mboxrd@z Thu Jan 1 00:00:00 1970 From: AL-KERNEL To: kernel-cve@kernelcve.org Subject: [CVE-2026-89928][MODERATE 7.0] KVM: x86/mmu: Consume the locked rmap value in the lockless rmap walk Date: Wed, 16 Sep 2026 14:25:07 -0400 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-AL-KERNEL-CVE: CVE-2026-89928 X-AL-KERNEL-Priority: MODERATE 7.0 X-AL-KERNEL-Severity: MODERATE 7.0 X-AL-KERNEL-Base-Severity: MODERATE X-AL-KERNEL-KPANIC: YES X-AL-KERNEL-ActionableScore: 5 X-AL-KERNEL-ActionableScore-Lower: 4 X-AL-KERNEL-Commit: 41debfc98526c0a95c41a62435aca0a70340a26d List-Id: CVE: CVE-2026-89928 Priority: MODERATE 7.0 AL-KERNEL base severity: MODERATE KPANIC flag: YES Patch: KVM: x86/mmu: Consume the locked rmap value in the lockless rmap walk Commit: 41debfc98526c0a95c41a62435aca0a70340a26d Upstream patch: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=41debfc98526c0a95c41a62435aca0a70340a26d Original CVE announcement: https://lore.kernel.org/linux-cve-announce/?q=CVE-2026-89928 Analysis date: Wed, 16 Sep 2026 14:25:07 -0400 ActionableScore: 5 ActionableScore lower bound: 4 Actionable bucket: Actionable Moderate / Strong Important candidate requiring manual review Manual review required: YES Summary: A KVM x86 MMU lockless rmap aging race can cause the host kernel to walk a freed `KVM_RMAP_MANY` `pte_list_desc` chain, leading to a slab use-after-free and likely host DoS, with unresolved exploitation leverage that requires manual review. ====================================================================== ABOUT THIS REPORT ====================================================================== The original Linux kernel CVE announcement for CVE-2026-89928 is available here: https://lore.kernel.org/linux-cve-announce/?q=CVE-2026-89928 The original announcement does not normally provide a security severity estimate, CVSS assessment, or enough information to determine whether the reported kernel bug represents a practically relevant security issue. This report was generated by AL-KERNEL, an AI-assisted Linux kernel vulnerability analysis system developed by Alexander Larkin. It combines an autonomous classifier with LLM-assisted technical analysis and a separate ActionableScore mechanism. The purpose of this report is to prioritize Linux kernel CVEs before manual review, identify cases that require prompt investigation, and support automatic closure of issues that are unlikely to have meaningful security impact. Published priority for this report: MODERATE 7.0 Manual review required: YES A detailed explanation of the methodology and priority rules is included at the end of this message. ====================================================================== AL-KERNEL CLASSIFICATION RESULT ====================================================================== CVE-2026-89928 MODERATE https://www.kernelcve.org/list/?q=CVE-2026-89928 CHECK WITH IMPACT FROM ORIG NN MODERATE Maybe valid. Check manually. Hints by AL-KERNEL: The best (paranoid) CVSS is 'AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H';*CWE-416;CWE-362;CWE-667;Other CVSS 'AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:H';BEST CVSS score: '7';DESCR 'A use-after-free can occur in KVM x86/mmu lockless rmap aging when an empty rmap causes the rmap lock to be elided but the later iterator re reads the rmap value. If a writer populates and then zaps a KVM_RMAP_MANY chain while the aging path is walking it without the rmap lock, the walker may follow freed pte_list_desc memory. For the CVSS the PR:L is used because reliable triggering requires control of a VM or a local KVM process, or guest code execution in an environment where KVM is exposed to tenants. The issue is not directly network reachable and depends on KVM MMU aging behavior rather than packet traffic. Impact is at least local or guest-to-host denial of service via kernel crash, and in the paranoid case may allow confidentiality or integrity impact because the bug is an rmap based slab use-after-free in KVM MMU code.';YES REQUIRES MANUAL CHECK; ,and ActionableScore result is Actionable Moderate / Strong Important candidate requiring manual review (with actual score 5) MAYBE VIRT UAF HARDWARE LINUS KPANIC - - checked ====================================================================== ACTIONABLESCORE ANALYSIS ====================================================================== ActionableScore=5 ActionableScoreLower=4 PrimitiveClass=CLASS_B RealUAF=YES HostAdminRequired=NO NamespaceScopedPrivilege=NO ImportantCandidate=YES ManualReview=REQUIRED AutoDowngradeAllowed=NO ## 1. ActionableScore * Raw conservative score: 3 * Conservative score: 4 * Raw paranoid score: 4 * Paranoid score: 5 * Final recommended bucket: **Actionable Moderate / Strong Important candidate requiring manual review**:: Conservative floor applied: 3 -> 4 because a real host-kernel UAF is established and host-admin-equivalent privilege is not positively required. Paranoid floor applied: 4 -> 5 because the stale object is active KVM MMU rmap state and the stale walk follows `pte_list_desc` / SPTE structures, leaving meaningful exploitation leverage unresolved. ## 2. Signal breakdown Conservative positive signals: * +2 Real UAF / active lifetime violation. The commit directly says the lockless rmap aging path can walk a `KVM_RMAP_MANY` `pte_list_desc` chain without the rmap lock while a writer frees that chain via `kmem_cache_free()`, giving a slab use-after-free. * +1 Reliable kernel crash / strong DoS. A host kernel UAF in KVM MMU rmap traversal realistically supports host crash or panic. Conservative negative signals: * No -2 host-admin penalty. Host-admin-equivalent privilege is not positively established. The relevant attacker model is at least a local VMM or process with `/dev/kvm` access, not necessarily host root. * No -1 race penalty. The bug is a race, but the commit says the empty-rmap path re-enables preemption and the interval between reads can span arbitrary scheduling delay. The evidence does not establish a narrow one-shot externally uncontrollable race. * No -1 rare hardware penalty. KVM/x86 is not rare hardware. The path may depend on `CONFIG_KVM_MMU_LOCKLESS_AGING=y` and shadow-MMU/rmap behavior, but this is not enough for a physical-only or rare-hardware reduction. Paranoid additional signal: * +1 Structured stale-object concern. The stale object is not a fixed passive buffer. The walker follows active KVM MMU rmap structures and consumes `pte_list_desc` / SPTE pointer state after possible free. This is meaningful unresolved Class B leverage, but not enough for Class A. Important non-awarded signals: * Strong exploitation leverage +2 not awarded. No controlled reclaim, attacker-shaped replacement object, arbitrary host read/write, callback control, or demonstrated guest-to-host escape is established. * KVM guest-to-host strong leverage not awarded. The evidence establishes host-side KVM UAF and possible host DoS, but not an independently useful guest-to-host corruption primitive. * Local unprivileged trigger +1 not awarded. `/dev/kvm` access or a VMM role is needed for the complete practical trigger model. Ordinary local-user reachability without such access is not proven. * Remote reachability +2 not awarded. This is not packet-triggered or network-reachable directly. * C/I impact not awarded as ActionableScore bonuses. Confidentiality or integrity impact is plausible only as paranoid review concern, not as a demonstrated primitive. * Extra availability +1 not awarded. The same host crash/DoS is already counted once. * Concrete repeated release/refcount +1 not awarded. There is no visible second `put`/`release`/refcount mutation on the same dangling reference. * Structured leverage is not upgraded to Class A. The patch establishes stale traversal, not controlled replacement or directed corruption. Repeated-release/refcount checklist: * First release can end lifetime: not applicable. * Exact same reference survives to second release: not established. * Second operation mutates lifetime/refcount: not established. * Concrete repeated release/refcount +1 awarded: no. * Paranoid repeated-refcount leverage +1 awarded: no. * FLOOR 5 from repeated release: no. ## 3. Reachability analysis The evaluated attacker roles are: * Malicious guest: guest activity can influence KVM MMU state, but the supplied evidence does not prove a pure guest-only trigger for the complete sequence. * Local VMM or host user with `/dev/kvm` access: this is the most plausible below-host-admin attacker model. Such a process can create and run VMs and may influence KVM MMU activity enough to reach the vulnerable path. * Host administrator: sufficient but not required by the supplied evidence. The trigger is best treated as local KVM/VMM reachable, not directly network reachable. Namespace-scoped privilege is not established and is not the relevant boundary here. The path depends on KVM x86 MMU rmap aging and `CONFIG_KVM_MMU_LOCKLESS_AGING=y`. The commit also refers to shadow MMU/rmap behavior. These are relevant configuration constraints, but not enough to classify the issue as rare hardware or host-admin-only. The race involves an empty-rmap lock elision followed by a second read of `rmap_head->val`. A writer can populate and later zap/free the `KVM_RMAP_MANY` chain while the aging path walks it unlocked. The commit explicitly notes that preemption is re-enabled on the empty path, so the gap between reads can be arbitrarily long. ## 4. Primitive and severity interpretation Exact primitive: slab use-after-free in KVM x86 MMU rmap aging. The stale storage is active structured kernel state, not a fixed async buffer. The stale path walks `pte_list_desc` and SPTE state through `for_each_rmap_spte_lockless()`. This is broader than a shallow cleanup-only stale dereference. There is no concrete repeated release/refcount operation. This is category A ordinary stale traversal, not category B second lifetime/refcount mutation through the same dangling reference. PrimitiveClass is CLASS_B because a real kernel lifetime/corruption primitive exists, but no controlled reclaim, arbitrary write, callback control, refcount takeover, or demonstrated LPE is established. Demonstrated consequence: host kernel UAF and likely host DoS/crash. Speculative consequence: confidentiality or integrity impact may be possible if the stale rmap traversal can be steered through reclaimed controlled memory, but that mechanism is not established by the patch. ImportantCandidate is YES because this is a KVM MMU rmap UAF in active host-kernel virtualization state with unresolved exploitation leverage beyond an ordinary NULL dereference. It needs Important-vs-Moderate manual review. AutoDowngradeAllowed is NO because automatic closure would discard a concrete host-kernel UAF in KVM MMU rmap traversal where stale active structures may be followed after free. This is not proven Important, but it is not safe to treat as an ordinary crash-only cleanup bug. Likely operational severity: Actionable Moderate at minimum, with Strong Important review warranted. ## 5. One-sentence report phrase A KVM x86 MMU lockless rmap aging race can cause the host kernel to walk a freed `KVM_RMAP_MANY` `pte_list_desc` chain, leading to a slab use-after-free and likely host DoS, with unresolved exploitation leverage that requires manual review. ## 6. Manual review recommendation MANUAL CHECK REQUIRED Reason: real host-kernel UAF in KVM MMU rmap traversal is established, and the stale path consumes active structured MMU state rather than only faulting on a trivial NULL pointer. ## 7. Call-site confidence Call-site confidence: high ====================================================================== UPSTREAM PATCH SUMMARY ====================================================================== Patch: KVM: x86/mmu: Consume the locked rmap value in the lockless rmap walk Commit: 41debfc98526c0a95c41a62435aca0a70340a26d Upstream URL: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=41debfc98526c0a95c41a62435aca0a70340a26d Commit description: __kvm_rmap_lock() deliberately elides the rmap lock when it observes an empty rmap. In that case kvm_rmap_lock_readonly() also re-enables preemption and returns zero, so the caller holds neither the rmap lock nor a preemption reference. The elision documents the invariant it relies on: * Elide the lock if the rmap is empty, as lockless walkers (read-only * mode) don't need to (and can't) walk an empty rmap, nor can they add * entries to the rmap. I.e. the only paths that process empty rmaps * do so while holding mmu_lock for write, and are mutually exclusive. kvm_rmap_age_gfn_range() ignores the returned value and unconditionally enters for_each_rmap_spte_lockless(). The iterator started with rmap_get_first(), which re-reads rmap_head->val rather than using the value returned by the lock. If a writer populates the rmap between the lock's read and the iterator's re-read, the aging path walks the newly installed rmap without holding its lock. For a KVM_RMAP_MANY rmap this leaves the walker following a pte_list_desc chain that it never locked. A writer holding mmu_lock for write may free that chain (e.g. kvm_zap_all_rmap_sptes() on the recycle path, or any rmap zap) via kmem_cache_free() while the walk is in progress, giving a slab use-after-free. Nothing serialises the two: the aging path runs without mmu_lock when CONFIG_KVM_MMU_LOCKLESS_AGING=y, and the rmap lock that would otherwise exclude the writer was elided. Because the empty path re-enables preemption, the interval between the two reads can span an arbitrary scheduling delay. Fix the class of bug by having the lockless walk consume the value returned by the lock instead of re-reading the rmap. Split rmap_get_first() into __rmap_get_first(), which starts an iterator from an already-read rmap value, and make for_each_rmap_spte_lockless() take that value and call __rmap_get_first() directly. kvm_rmap_age_gfn_range() passes the value returned by kvm_rmap_lock_readonly(): when the lock was elided the value is zero, __rmap_get_first() returns NULL, and the walk is skipped. No lockless walker re-reads the rmap, so the lock-elision invariant cannot be violated, and no lock()-without-paired-unlock() path is added to the aging code. Fixes: af3b6a9 ("KVM: x86/mmu: Walk rmaps (shadow MMU) without holding mmu_lock when aging gfns") Suggested-by: Sean Christopherson Cc: stable@vger.kernel.org Signed-off-by: Phil Rosenthal Link: https://patch.msgid.link/20260720-rmap-age-elided-submit-v2-1-668973030d47@phil.gs Signed-off-by: Sean Christopherson Signed-off-by: Greg Kroah-Hartman Changed files: arch/x86/kvm/mmu/mmu.c Diff excerpt: Not included in this email. See the upstream URL for the full patch. Full patch: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=41debfc98526c0a95c41a62435aca0a70340a26d ====================================================================== DETAILED REPORT METHODOLOGY ====================================================================== The original Linux kernel CVE announcement for CVE-2026-89928 can be found here: https://lore.kernel.org/linux-cve-announce/?q=CVE-2026-89928 The original CVE announcement normally does not include a security-level estimate. In particular, it may not contain a CVSS assessment, an impact level, or enough information to determine whether the reported bug is a practically relevant security issue. One purpose of this parallel CVE list is to provide that missing technical and prioritization information. The original goal of the AL-KERNEL project was to prioritize Linux kernel CVE analysis automatically before manual review. The system can also help identify non-security issues that may be suitable for automatic closure. This report was generated by AL-KERNEL, an AI-assisted Linux kernel vulnerability analysis system developed by Alexander Larkin. The first analysis stage combines an autonomous classifier with additional LLM-based analysis. The autonomous classifier runs locally on a CPU and is based on a backpropagation neural network. Together, these mechanisms produce a technical vulnerability description, identify likely weakness types, estimate CVSS severity, and provide input for ActionableScore. Two CVSS estimates are retained because incomplete kernel vulnerability information often permits more than one defensible interpretation: Conservative CVSS vector: AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:H The Best / paranoid CVSS vector: AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H The Best / paranoid CVSS score: 7 The conservative vector represents a lower-impact interpretation. The Best/paranoid vector intentionally represents a plausible upper-bound interpretation and should not automatically be treated as demonstrated real-world impact. CVSS may also need to be adjusted for a particular Linux deployment, because actual reachability, privileges, enabled kernel configuration, hardware, namespaces, exposed device nodes, and other environmental conditions can differ significantly between systems. A separate ActionableScore mechanism evaluates practical remediation urgency. Its analysis may include reachability, attack prerequisites, subsystem exposure, memory-corruption characteristics, denial-of-service reliability, and possible confidentiality, integrity, or privilege-escalation impact. Conservative ActionableScore: 4 Paranoid ActionableScore: 5 The final base severity is taken directly from the second tab-separated field of the AL-KERNEL classification result. ActionableScore does not replace or independently override that final AL-KERNEL decision, and if ActionableScore adjusted impact level of ALKERNEL, then you would see self-readable flags above like INCREASED_TO_HIGH_BASED_ON_ACTIONABLESCOREHIGHEREQTHAN7. For an AL-KERNEL result of MODERATE, this report uses the following additional presentation split: ActionableScore below 5 -> MODERATE REGULAR ActionableScore 5 or more -> MODERATE 7.0 The distinction between MODERATE REGULAR and MODERATE 7.0 makes it possible to identify Moderate issues that should receive manual analysis and fixes before lower-priority MODERATE REGULAR issues. In many cases, MODERATE REGULAR fixes may wait for a later rebase or routine update. There is one override in which MODERATE REGULAR becomes MODERATE 7.0 even when the ActionableScore is below 5. When the AL-KERNEL result contains the KPANIC flag, a MODERATE result is always presented as MODERATE 7.0. The KPANIC flag selected with few regexps without usage of AI at all, so it helps to detect cases when Kernel Crash happens and similar (to filter False-Negative results from the LLM usage). KPANIC indicates that a reliable kernel crash, kernel panic, or similarly serious kernel availability impact was identified by the classification workflow. AL-KERNEL base severity for this report: MODERATE KPANIC detected for this report: YES Published priority for this report (same as in Subject): MODERATE 7.0 These results are intended to support engineering triage. They are machine-generated estimates, and cases marked for manual review should be validated by a human security engineer before final disposition. For more info read docs linked from here: https://kernelcve.org/ (and you can submit you own patch there to generate such a report for non-existant CVE-id yet). Note that in many cases this AI tool selects higher severity, than real is (means you can expect Importants instead of Moderate 7.0 or Moderates 7.0 instead of regular Moderates). If you see such cases, please use reply email interface to add additional manual analyses info to this particular CVE. And please, please, let me know when you see Lows instead of Importants or Important instead of Low (because particular for such cases I need to tune this AI tool to make it better for this one and next similar). My contact email for such notifications is alexanjelausa@gmail.com (and both send reply to CVE record itself too and see "reply" button below for howto reply).