...
 
Commits (3)
  • Christophe Leroy's avatar
    powerpc/kasan: Fix shadow memory protection with CONFIG_KASAN_VMALLOC · af3d0a68
    Christophe Leroy authored
    With CONFIG_KASAN_VMALLOC, new page tables are created at the time
    shadow memory for vmalloc area is unmapped. If some parts of the
    page table still have entries to the zero page shadow memory, the
    entries are wrongly marked RW.
    
    With CONFIG_KASAN_VMALLOC, almost the entire kernel address space
    is managed by KASAN. To make it simple, just create KASAN page tables
    for the entire kernel space at kasan_init(). That doesn't use much
    more space, and that's anyway already done for hash platforms.
    
    Fixes: 3d4247fc ("powerpc/32: Add support of KASAN_VMALLOC")
    Signed-off-by: default avatarChristophe Leroy <christophe.leroy@c-s.fr>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/ef5248fc1f496c6b0dfdb59380f24968f25f75c5.1583513368.git.christophe.leroy@c-s.fr
    af3d0a68
  • Greg Kurz's avatar
    KVM: PPC: Fix kernel crash with PR KVM · 1d0c32ec
    Greg Kurz authored
    With PR KVM, shutting down a VM causes the host kernel to crash:
    
    [  314.219284] BUG: Unable to handle kernel data access on read at 0xc00800000176c638
    [  314.219299] Faulting instruction address: 0xc008000000d4ddb0
    cpu 0x0: Vector: 300 (Data Access) at [c00000036da077a0]
        pc: c008000000d4ddb0: kvmppc_mmu_pte_flush_all+0x68/0xd0 [kvm_pr]
        lr: c008000000d4dd94: kvmppc_mmu_pte_flush_all+0x4c/0xd0 [kvm_pr]
        sp: c00000036da07a30
       msr: 900000010280b033
       dar: c00800000176c638
     dsisr: 40000000
      current = 0xc00000036d4c0000
      paca    = 0xc000000001a00000   irqmask: 0x03   irq_happened: 0x01
        pid   = 1992, comm = qemu-system-ppc
    Linux version 5.6.0-master-gku+ (greg@palmb) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #17 SMP Wed Mar 18 13:49:29 CET 2020
    enter ? for help
    [c00000036da07ab0] c008000000d4fbe0 kvmppc_mmu_destroy_pr+0x28/0x60 [kvm_pr]
    [c00000036da07ae0] c0080000009eab8c kvmppc_mmu_destroy+0x34/0x50 [kvm]
    [c00000036da07b00] c0080000009e50c0 kvm_arch_vcpu_destroy+0x108/0x140 [kvm]
    [c00000036da07b30] c0080000009d1b50 kvm_vcpu_destroy+0x28/0x80 [kvm]
    [c00000036da07b60] c0080000009e4434 kvm_arch_destroy_vm+0xbc/0x190 [kvm]
    [c00000036da07ba0] c0080000009d9c2c kvm_put_kvm+0x1d4/0x3f0 [kvm]
    [c00000036da07c00] c0080000009da760 kvm_vm_release+0x38/0x60 [kvm]
    [c00000036da07c30] c000000000420be0 __fput+0xe0/0x310
    [c00000036da07c90] c0000000001747a0 task_work_run+0x150/0x1c0
    [c00000036da07cf0] c00000000014896c do_exit+0x44c/0xd00
    [c00000036da07dc0] c0000000001492f4 do_group_exit+0x64/0xd0
    [c00000036da07e00] c000000000149384 sys_exit_group+0x24/0x30
    [c00000036da07e20] c00000000000b9d0 system_call+0x5c/0x68
    
    This is caused by a use-after-free in kvmppc_mmu_pte_flush_all()
    which dereferences vcpu->arch.book3s which was previously freed by
    kvmppc_core_vcpu_free_pr(). This happens because kvmppc_mmu_destroy()
    is called after kvmppc_core_vcpu_free() since commit ff030fdf
    ("KVM: PPC: Move kvm_vcpu_init() invocation to common code").
    
    The kvmppc_mmu_destroy() helper calls one of the following depending
    on the KVM backend:
    
    - kvmppc_mmu_destroy_hv() which does nothing (Book3s HV)
    
    - kvmppc_mmu_destroy_pr() which undoes the effects of
      kvmppc_mmu_init() (Book3s PR 32-bit)
    
    - kvmppc_mmu_destroy_pr() which undoes the effects of
      kvmppc_mmu_init() (Book3s PR 64-bit)
    
    - kvmppc_mmu_destroy_e500() which does nothing (BookE e500/e500mc)
    
    It turns out that this is only relevant to PR KVM actually. And both
    32 and 64 backends need vcpu->arch.book3s to be valid when calling
    kvmppc_mmu_destroy_pr(). So instead of calling kvmppc_mmu_destroy()
    from kvm_arch_vcpu_destroy(), call kvmppc_mmu_destroy_pr() at the
    beginning of kvmppc_core_vcpu_free_pr(). This is consistent with
    kvmppc_mmu_init() being the last call in kvmppc_core_vcpu_create_pr().
    
    For the same reason, if kvmppc_core_vcpu_create_pr() returns an
    error then this means that kvmppc_mmu_init() was either not called
    or failed, in which case kvmppc_mmu_destroy() should not be called.
    Drop the line in the error path of kvm_arch_vcpu_create().
    
    Fixes: ff030fdf ("KVM: PPC: Move kvm_vcpu_init() invocation to common code")
    Signed-off-by: default avatarGreg Kurz <groug@kaod.org>
    Reviewed-by: default avatarSean Christopherson <sean.j.christopherson@intel.com>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/158455341029.178873.15248663726399374882.stgit@bahia.lan
    1d0c32ec
  • Linus Torvalds's avatar
    Merge tag 'powerpc-5.6-5' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux · c63c50fc
    Linus Torvalds authored
    Pull powerpc fixes from Michael Ellerman:
     "Two fixes for bugs introduced this cycle:
    
       - fix a crash when shutting down a KVM PR guest (our original style
         of KVM which doesn't use hypervisor mode)
    
       - fix for the recently added 32-bit KASAN_VMALLOC support
    
      Thanks to: Christophe Leroy, Greg Kurz, Sean Christopherson"
    
    * tag 'powerpc-5.6-5' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
      KVM: PPC: Fix kernel crash with PR KVM
      powerpc/kasan: Fix shadow memory protection with CONFIG_KASAN_VMALLOC
    c63c50fc
......@@ -1817,6 +1817,7 @@ static void kvmppc_core_vcpu_free_pr(struct kvm_vcpu *vcpu)
{
struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
kvmppc_mmu_destroy_pr(vcpu);
free_page((unsigned long)vcpu->arch.shared & PAGE_MASK);
#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
kfree(vcpu->arch.shadow_vcpu);
......
......@@ -759,7 +759,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
return 0;
out_vcpu_uninit:
kvmppc_mmu_destroy(vcpu);
kvmppc_subarch_vcpu_uninit(vcpu);
return err;
}
......@@ -792,7 +791,6 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
kvmppc_core_vcpu_free(vcpu);
kvmppc_mmu_destroy(vcpu);
kvmppc_subarch_vcpu_uninit(vcpu);
}
......
......@@ -120,12 +120,6 @@ static void __init kasan_unmap_early_shadow_vmalloc(void)
unsigned long k_cur;
phys_addr_t pa = __pa(kasan_early_shadow_page);
if (!early_mmu_has_feature(MMU_FTR_HPTE_TABLE)) {
int ret = kasan_init_shadow_page_tables(k_start, k_end);
if (ret)
panic("kasan: kasan_init_shadow_page_tables() failed");
}
for (k_cur = k_start & PAGE_MASK; k_cur < k_end; k_cur += PAGE_SIZE) {
pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(k_cur), k_cur), k_cur);
pte_t *ptep = pte_offset_kernel(pmd, k_cur);
......@@ -143,7 +137,8 @@ void __init kasan_mmu_init(void)
int ret;
struct memblock_region *reg;
if (early_mmu_has_feature(MMU_FTR_HPTE_TABLE)) {
if (early_mmu_has_feature(MMU_FTR_HPTE_TABLE) ||
IS_ENABLED(CONFIG_KASAN_VMALLOC)) {
ret = kasan_init_shadow_page_tables(KASAN_SHADOW_START, KASAN_SHADOW_END);
if (ret)
......