Skip to content

Commit 045e1d5

Browse files
committed
KVM: s390: Fix incorrect usage of mmu_notifier_register()
JIRA: https://issues.redhat.com/browse/RHEL-113440 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 d99e990 commit 045e1d5

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
@@ -622,6 +622,17 @@ int kvm_s390_pv_init_vm(struct kvm *kvm, u16 *rc, u16 *rrc)
622622
int cc, ret;
623623
u16 dummy;
624624

625+
/* Add the notifier only once. No races because we hold kvm->lock */
626+
if (kvm->arch.pv.mmu_notifier.ops != &kvm_s390_pv_mmu_notifier_ops) {
627+
/* The notifier will be unregistered when the VM is destroyed */
628+
kvm->arch.pv.mmu_notifier.ops = &kvm_s390_pv_mmu_notifier_ops;
629+
ret = mmu_notifier_register(&kvm->arch.pv.mmu_notifier, kvm->mm);
630+
if (ret) {
631+
kvm->arch.pv.mmu_notifier.ops = NULL;
632+
return ret;
633+
}
634+
}
635+
625636
ret = kvm_s390_pv_alloc_vm(kvm);
626637
if (ret)
627638
return ret;
@@ -657,11 +668,6 @@ int kvm_s390_pv_init_vm(struct kvm *kvm, u16 *rc, u16 *rrc)
657668
return -EIO;
658669
}
659670
kvm->arch.gmap->guest_handle = uvcb.guest_handle;
660-
/* Add the notifier only once. No races because we hold kvm->lock */
661-
if (kvm->arch.pv.mmu_notifier.ops != &kvm_s390_pv_mmu_notifier_ops) {
662-
kvm->arch.pv.mmu_notifier.ops = &kvm_s390_pv_mmu_notifier_ops;
663-
mmu_notifier_register(&kvm->arch.pv.mmu_notifier, kvm->mm);
664-
}
665671
return 0;
666672
}
667673

0 commit comments

Comments
 (0)