WSL2-Linux-Kernel/arch/x86/kvm
Kazuki Takiguchi f88a6977f8 KVM: x86/mmu: Fix race condition in direct_page_fault
commit 47b0c2e4c2 upstream.

make_mmu_pages_available() must be called with mmu_lock held for write.
However, if the TDP MMU is used, it will be called with mmu_lock held for
read.
This function does nothing unless shadow pages are used, so there is no
race unless nested TDP is used.
Since nested TDP uses shadow pages, old shadow pages may be zapped by this
function even when the TDP MMU is enabled.
Since shadow pages are never allocated by kvm_tdp_mmu_map(), a race
condition can be avoided by not calling make_mmu_pages_available() if the
TDP MMU is currently in use.

I encountered this when repeatedly starting and stopping nested VM.
It can be artificially caused by allocating a large number of nested TDP
SPTEs.

For example, the following BUG and general protection fault are caused in
the host kernel.

pte_list_remove: 00000000cd54fc10 many->many
------------[ cut here ]------------
kernel BUG at arch/x86/kvm/mmu/mmu.c:963!
invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
RIP: 0010:pte_list_remove.cold+0x16/0x48 [kvm]
Call Trace:
 <TASK>
 drop_spte+0xe0/0x180 [kvm]
 mmu_page_zap_pte+0x4f/0x140 [kvm]
 __kvm_mmu_prepare_zap_page+0x62/0x3e0 [kvm]
 kvm_mmu_zap_oldest_mmu_pages+0x7d/0xf0 [kvm]
 direct_page_fault+0x3cb/0x9b0 [kvm]
 kvm_tdp_page_fault+0x2c/0xa0 [kvm]
 kvm_mmu_page_fault+0x207/0x930 [kvm]
 npf_interception+0x47/0xb0 [kvm_amd]
 svm_invoke_exit_handler+0x13c/0x1a0 [kvm_amd]
 svm_handle_exit+0xfc/0x2c0 [kvm_amd]
 kvm_arch_vcpu_ioctl_run+0xa79/0x1780 [kvm]
 kvm_vcpu_ioctl+0x29b/0x6f0 [kvm]
 __x64_sys_ioctl+0x95/0xd0
 do_syscall_64+0x5c/0x90

general protection fault, probably for non-canonical address
0xdead000000000122: 0000 [#1] PREEMPT SMP NOPTI
RIP: 0010:kvm_mmu_commit_zap_page.part.0+0x4b/0xe0 [kvm]
Call Trace:
 <TASK>
 kvm_mmu_zap_oldest_mmu_pages+0xae/0xf0 [kvm]
 direct_page_fault+0x3cb/0x9b0 [kvm]
 kvm_tdp_page_fault+0x2c/0xa0 [kvm]
 kvm_mmu_page_fault+0x207/0x930 [kvm]
 npf_interception+0x47/0xb0 [kvm_amd]

CVE: CVE-2022-45869
Fixes: a2855afc7e ("KVM: x86/mmu: Allow parallel page faults for the TDP MMU")
Signed-off-by: Kazuki Takiguchi <takiguchi.kazuki171@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-12-08 11:28:43 +01:00
..
mmu KVM: x86/mmu: Fix race condition in direct_page_fault 2022-12-08 11:28:43 +01:00
svm KVM: x86: remove exit_int_info warning in svm_handle_exit 2022-12-02 17:41:09 +01:00
vmx KVM: x86: add kvm_leave_nested 2022-12-02 17:41:09 +01:00
Kconfig ARM: 2021-06-28 15:40:51 -07:00
Makefile KVM: stats: Add fd-based API to read binary stats data 2021-06-24 11:47:57 -04:00
cpuid.c KVM: x86: Mask off reserved bits in CPUID.8000001FH 2022-11-10 18:15:41 +01:00
cpuid.h KVM: x86: Move reverse CPUID helpers to separate header file 2021-04-26 05:27:13 -04:00
debugfs.c KVM: x86: Check for rmaps allocation 2022-01-11 15:35:15 +01:00
emulate.c KVM: x86: emulator: update the emulation mode after CR0 write 2022-11-10 18:15:42 +01:00
fpu.h KVM: x86: Move FPU register accessors into fpu.h 2021-06-17 13:09:24 -04:00
hyperv.c KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC wasn't activated 2022-04-08 14:24:07 +02:00
hyperv.h KVM: x86: Query vcpu->vcpu_idx directly and drop its accessor 2021-09-22 10:33:11 -04:00
i8254.c KVM: x86: Migrate the PIT only if vcpu0 is migrated, not any BSP 2021-08-02 11:01:51 -04:00
i8254.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
i8259.c x86: Fix typo s/ECLR/ELCR/ for the PIC register 2021-08-10 23:31:44 +02:00
ioapic.c Revert "x86/kvm: fix vcpu-id indexed array sizes" 2021-11-12 15:05:47 +01:00
ioapic.h x86/kvm: remove unused ack_notifier callbacks 2021-12-22 09:32:34 +01:00
irq.c KVM: x86/xen: Add event channel interrupt vector upcall 2021-02-04 14:19:39 +00:00
irq.h x86/kvm: remove unused ack_notifier callbacks 2021-12-22 09:32:34 +01:00
irq_comm.c x86: Fix various typos in comments 2021-03-18 15:31:53 +01:00
kvm_cache_regs.h KVM: x86: Introduce KVM_GET_SREGS2 / KVM_SET_SREGS2 2021-06-17 13:09:47 -04:00
kvm_emulate.h KVM: x86/emulator: Emulate RDPID only if it is enabled in guest 2022-04-13 20:59:00 +02:00
kvm_onhyperv.c KVM: x86: hyper-v: Move the remote TLB flush logic out of vmx 2021-06-17 13:09:36 -04:00
kvm_onhyperv.h KVM: x86: hyper-v: Move the remote TLB flush logic out of vmx 2021-06-17 13:09:36 -04:00
lapic.c KVM: LAPIC: Drop pending LAPIC timer injection when canceling the timer 2022-06-09 10:23:13 +02:00
lapic.h KVM: x86: Add a return code to kvm_apic_accept_events 2021-06-17 13:09:31 -04:00
mmu.h KVM: x86: Reinitialize context if host userspace toggles EFER.LME 2022-04-08 14:24:03 +02:00
mtrr.c KVM: x86: Add helper to consolidate "raw" reserved GPA mask calculations 2021-02-04 09:27:30 -05:00
pmu.c KVM: x86/pmu: Fix and isolate TSX-specific performance event logic 2022-04-13 20:59:00 +02:00
pmu.h KVM: x86/pmu: Update AMD PMC sample period to fix guest NMI-watchdog 2022-04-27 14:39:00 +02:00
reverse_cpuid.h KVM: SEV: Mask CPUID[0x8000001F].eax according to supported features 2021-04-26 05:27:15 -04:00
trace.h KVM: x86: Trace re-injected exceptions 2022-11-10 18:15:24 +01:00
tss.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
x86.c KVM: x86: add kvm_leave_nested 2022-12-02 17:41:09 +01:00
x86.h lockdep: Fix -Wunused-parameter for _THIS_IP_ 2022-09-20 12:39:42 +02:00
xen.c KVM: x86/xen: Fix runstate updates to be atomic when preempting vCPU 2022-02-23 12:03:07 +01:00
xen.h KVM: x86: do not set st->preempted when going back to user space 2022-08-11 13:07:51 +02:00