Skip to content

Commit a71b2dd

Browse files
committed
KVM: s390: Fix incorrect usage of mmu_notifier_register()
JIRA: https://issues.redhat.com/browse/RHEL-113452 commit 185d903 Author: Claudio Imbrenda <imbrenda@linux.ibm.com> Date: Mon Aug 25 17:18:30 2025 +0200 KVM: s390: Fix incorrect usage of mmu_notifier_register() If mmu_notifier_register() fails, for example because a signal was pending, the mmu_notifier will not be registered. But when the VM gets destroyed, it will get unregistered anyway and that will cause one extra mmdrop(), which will eventually cause the mm of the process to be freed too early, and cause a use-after free. This bug happens rarely, and only when secure guests are involved. The solution is to check the return value of mmu_notifier_register() and return it to the caller (ultimately it will be propagated all the way to userspace). In case of -EINTR, userspace will try again. Fixes: ca2fd06 ("KVM: s390: pv: add mmu_notifier") Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Reviewed-by: Christian Borntraeger <borntraeger@linux.ibm.com> Reviewed-by: David Hildenbrand <david@redhat.com> Reviewed-by: Steffen Eiden <seiden@linux.ibm.com> Reviewed-by: Christoph Schlameuss <schlameuss@linux.ibm.com> Signed-off-by: Janosch Frank <frankja@linux.ibm.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
1 parent e52e022 commit a71b2dd

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

arch/s390/kvm/pv.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,17 @@ int kvm_s390_pv_init_vm(struct kvm *kvm, u16 *rc, u16 *rrc)
564564
int cc, ret;
565565
u16 dummy;
566566

567+
/* Add the notifier only once. No races because we hold kvm->lock */
568+
if (kvm->arch.pv.mmu_notifier.ops != &kvm_s390_pv_mmu_notifier_ops) {
569+
/* The notifier will be unregistered when the VM is destroyed */
570+
kvm->arch.pv.mmu_notifier.ops = &kvm_s390_pv_mmu_notifier_ops;
571+
ret = mmu_notifier_register(&kvm->arch.pv.mmu_notifier, kvm->mm);
572+
if (ret) {
573+
kvm->arch.pv.mmu_notifier.ops = NULL;
574+
return ret;
575+
}
576+
}
577+
567578
ret = kvm_s390_pv_alloc_vm(kvm);
568579
if (ret)
569580
return ret;
@@ -599,11 +610,6 @@ int kvm_s390_pv_init_vm(struct kvm *kvm, u16 *rc, u16 *rrc)
599610
return -EIO;
600611
}
601612
kvm->arch.gmap->guest_handle = uvcb.guest_handle;
602-
/* Add the notifier only once. No races because we hold kvm->lock */
603-
if (kvm->arch.pv.mmu_notifier.ops != &kvm_s390_pv_mmu_notifier_ops) {
604-
kvm->arch.pv.mmu_notifier.ops = &kvm_s390_pv_mmu_notifier_ops;
605-
mmu_notifier_register(&kvm->arch.pv.mmu_notifier, kvm->mm);
606-
}
607613
return 0;
608614
}
609615

0 commit comments

Comments
 (0)