• Mingwei Zhang's avatar
    KVM: x86/mmu: fix potential races when walking host page table · 44187235
    Mingwei Zhang authored
    KVM uses lookup_address_in_mm() to detect the hugepage size that the host
    uses to map a pfn.  The function suffers from several issues:
    
     - no usage of READ_ONCE(*). This allows multiple dereference of the same
       page table entry. The TOCTOU problem because of that may cause KVM to
       incorrectly treat a newly generated leaf entry as a nonleaf one, and
       dereference the content by using its pfn value.
    
     - the information returned does not match what KVM needs; for non-present
       entries it returns the level at which the walk was terminated, as long
       as the entry is not 'none'.  KVM needs level information of only 'present'
       entries, otherwise it may regard a non-present PXE entry as a present
       large page mapping.
    
     - the function is not safe for mappings that can be torn down, because it
       does not disable IRQs and because it returns a PTE pointer which is never
       safe to dereference after the function returns.
    
    So implement the logic for walking host page tables directly in KVM, and
    stop using lookup_address_in_mm().
    
    Cc: Sean Christopherson <seanjc@google.com>
    Cc: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: default avatarMingwei Zhang <mizhang@google.com>
    Message-Id: <20220429031757.2042406-1-mizhang@google.com>
    [Inline in host_pfn_mapping_level, ensure no semantic change for its
     callers. - Paolo]
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    44187235
mmu.c 175 KB