linux-stable/Documentation/virt/kvm
Sean Christopherson 771dfb3c53 KVM: x86: Protect userspace MSR filter with SRCU, and set atomically-ish
[ Upstream commit b318e8decf ]

Fix a plethora of issues with MSR filtering by installing the resulting
filter as an atomic bundle instead of updating the live filter one range
at a time.  The KVM_X86_SET_MSR_FILTER ioctl() isn't truly atomic, as
the hardware MSR bitmaps won't be updated until the next VM-Enter, but
the relevant software struct is atomically updated, which is what KVM
really needs.

Similar to the approach used for modifying memslots, make arch.msr_filter
a SRCU-protected pointer, do all the work configuring the new filter
outside of kvm->lock, and then acquire kvm->lock only when the new filter
has been vetted and created.  That way vCPU readers either see the old
filter or the new filter in their entirety, not some half-baked state.

Yuan Yao pointed out a use-after-free in ksm_msr_allowed() due to a
TOCTOU bug, but that's just the tip of the iceberg...

  - Nothing is __rcu annotated, making it nigh impossible to audit the
    code for correctness.
  - kvm_add_msr_filter() has an unpaired smp_wmb().  Violation of kernel
    coding style aside, the lack of a smb_rmb() anywhere casts all code
    into doubt.
  - kvm_clear_msr_filter() has a double free TOCTOU bug, as it grabs
    count before taking the lock.
  - kvm_clear_msr_filter() also has memory leak due to the same TOCTOU bug.

The entire approach of updating the live filter is also flawed.  While
installing a new filter is inherently racy if vCPUs are running, fixing
the above issues also makes it trivial to ensure certain behavior is
deterministic, e.g. KVM can provide deterministic behavior for MSRs with
identical settings in the old and new filters.  An atomic update of the
filter also prevents KVM from getting into a half-baked state, e.g. if
installing a filter fails, the existing approach would leave the filter
in a half-baked state, having already committed whatever bits of the
filter were already processed.

[*] https://lkml.kernel.org/r/20210312083157.25403-1-yaoyuan0329os@gmail.com

Fixes: 1a155254ff ("KVM: x86: Introduce MSR filtering")
Cc: stable@vger.kernel.org
Cc: Alexander Graf <graf@amazon.com>
Reported-by: Yuan Yao <yaoyuan0329os@gmail.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-Id: <20210316184436.2544875-2-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2021-03-30 14:31:53 +02:00
..
arm Documentation/kvm/arm: improve description of HVC_SOFT_RESTART 2020-09-11 19:29:10 +01:00
devices KVM: arm64: Fix some documentation build warnings 2020-10-02 09:12:25 +01:00
amd-memory-encryption.rst docs: kvm: fix referenced ioctl symbol 2020-09-09 11:19:39 -06:00
api.rst KVM: x86: Protect userspace MSR filter with SRCU, and set atomically-ish 2021-03-30 14:31:53 +02:00
cpuid.rst x86/kvm: Reserve KVM_FEATURE_MSI_EXT_DEST_ID 2020-10-28 13:52:05 -04:00
halt-polling.rst docs: virt: convert halt-polling.txt to ReST format 2020-02-12 20:09:50 +01:00
hypercalls.rst docs: fix broken references to text files 2020-04-20 15:35:59 -06:00
index.rst docs/virt/kvm: Document configuring and running nested guests 2020-05-06 05:45:47 -04:00
locking.rst KVM: Documentation: Update fast page fault for indirect sp 2020-03-16 17:58:56 +01:00
mmu.rst KVM: mmu: Fix SPTE encoding of MMIO generation upper half 2020-12-11 19:18:43 -05:00
msr.rst KVM: x86: announce KVM_FEATURE_ASYNC_PF_INT 2020-06-01 04:26:08 -04:00
nested-vmx.rst docs: kvm: Replace HTTP links with HTTPS ones 2020-07-13 09:34:07 -06:00
ppc-pv.rst docs: kvm: Convert ppc-pv.txt to ReST format 2020-02-12 20:10:05 +01:00
review-checklist.rst docs: fix broken references for ReST files that moved around 2020-04-20 15:45:03 -06:00
running-nested-guests.rst docs/virt/kvm: Document configuring and running nested guests 2020-05-06 05:45:47 -04:00
s390-diag.rst docs: kvm: Convert s390-diag.txt to ReST format 2020-02-12 20:10:06 +01:00
s390-pv-boot.rst DOCUMENTATION: Protected virtual machine introduction and IPL 2020-02-27 19:47:12 +01:00
s390-pv.rst Documentation: virt: kvm/s390-pv: drop doubled words 2020-07-05 14:42:17 -06:00
timekeeping.rst docs: kvm: Convert timekeeping.txt to ReST format 2020-02-12 20:10:06 +01:00
vcpu-requests.rst