Commit 649ff5c
committed
KVM: x86: Fix shadow paging use-after-free due to unexpected role
jira VULN-191426
cve CVE-2026-53359
commit-author Paolo Bonzini <pbonzini@redhat.com>
commit -
commit-source-sha 81ccda3
commit-source https://lore.kernel.org/all/20260626112634.1778506-1-pbonzini@redhat.com/
upstream-diff |
This is a HAND-PORT, not a cherry-pick. Upstream commit
81ccda3 fixes kvm_mmu_get_child_sp() by adding
spte_to_child_sp(*sptep)->role.word == role.word to its -EEXIST
reuse guard, on top of the unexpected-GFN check. That function does
not exist on this 4.18-based tree (see the prerequisite "unexpected
GFN" commit for the full rationale); the equivalent guard lives in
the shared helper kvm_mmu_child_sp_matches() applied at the three
fault-path reuse sites. This commit adds the role.word comparison
to that helper, using kvm_mmu_child_role() to derive the expected
role exactly as kvm_mmu_get_page() does. Functionally equivalent to
upstream.
Commit 0cb2af2 ("KVM: x86: Fix shadow paging use-after-free due to
unexpected GFN") fixed a shadow paging mismatch between stored and
computed GFNs. A similar hole remains if the modified PDE points to a
non-leaf page: the gfn can be made to match, but the role does not. The
original large 2MB page creates a kvm_mmu_page with direct=1, while the
new 4KB mapping needs one with direct=0; because the reuse path did not
compare the role, the direct=1 page was reused. Installing a leaf SPTE
then records an rmap entry under the walk's gfn, but when that child is
zapped its parent has direct=1 and kvm_mmu_page_get_gfn() computes the
gfn as sp->gfn + index instead of using sp->gfns[], so the recorded
entry is not removed. When the memslot is dropped the shadow page is
freed but the rmap entry survives, and later walks dereference an sptep
in the freed page, causing the use-after-free.
Fixes: 2032a93 ("KVM: MMU: Don't allocate gfns page for direct mmu pages")
Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
Signed-off-by: Shreeya Patel <spatel@ciq.com>1 parent 51e2c75 commit 649ff5c
1 file changed
Lines changed: 13 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2110 | 2110 | | |
2111 | 2111 | | |
2112 | 2112 | | |
2113 | | - | |
| 2113 | + | |
2114 | 2114 | | |
2115 | | - | |
2116 | | - | |
2117 | | - | |
2118 | | - | |
2119 | | - | |
2120 | | - | |
2121 | | - | |
2122 | | - | |
| 2115 | + | |
| 2116 | + | |
| 2117 | + | |
| 2118 | + | |
| 2119 | + | |
| 2120 | + | |
| 2121 | + | |
| 2122 | + | |
| 2123 | + | |
2123 | 2124 | | |
2124 | 2125 | | |
2125 | 2126 | | |
2126 | 2127 | | |
2127 | 2128 | | |
2128 | 2129 | | |
| 2130 | + | |
2129 | 2131 | | |
2130 | 2132 | | |
2131 | 2133 | | |
2132 | 2134 | | |
2133 | 2135 | | |
2134 | 2136 | | |
2135 | | - | |
| 2137 | + | |
| 2138 | + | |
2136 | 2139 | | |
2137 | 2140 | | |
2138 | 2141 | | |
| |||
0 commit comments