Extract the VMA lookup and metadata snapshotting logic from kvm_s2_fault_pin_pfn() into a tightly-scoped sub-helper. This refactoring structurally fixes a TOCTOU (Time-Of-Check to Time-Of-Use) vulnerability and Use-After-Free risk involving the vma pointer. In the previous layout, the mmap_read_lock is taken, the vma is looked up, and then the lock is dropped before the function continues to map the PFN. While an explicit vma = NULL safeguard was present, the vma variable was still lexically in scope for the remainder of the function. By isolating the locked region into kvm_s2_fault_get_vma_info(), the vma pointer becomes a local variable strictly confined to that sub-helper. Because the pointer's scope literally ends when the sub-helper returns, it is not possible for the subsequent page fault logic in kvm_s2_fault_pin_pfn() to accidentally access the vanished VMA, eliminating this bug class by design. Signed-off-by: Fuad Tabba --- arch/arm64/kvm/mmu.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index d56c6422ca5f..344a477e1bff 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1740,7 +1740,7 @@ struct kvm_s2_fault { vm_flags_t vm_flags; }; -static int kvm_s2_fault_pin_pfn(struct kvm_s2_fault *fault) +static int kvm_s2_fault_get_vma_info(struct kvm_s2_fault *fault) { struct vm_area_struct *vma; struct kvm *kvm = fault->vcpu->kvm; @@ -1774,9 +1774,6 @@ static int kvm_s2_fault_pin_pfn(struct kvm_s2_fault *fault) fault->is_vma_cacheable = kvm_vma_is_cacheable(vma); - /* Don't use the VMA after the unlock -- it may have vanished */ - vma = NULL; - /* * Read mmu_invalidate_seq so that KVM can detect if the results of * vma_lookup() or __kvm_faultin_pfn() become stale prior to @@ -1788,6 +1785,17 @@ static int kvm_s2_fault_pin_pfn(struct kvm_s2_fault *fault) fault->mmu_seq = kvm->mmu_invalidate_seq; mmap_read_unlock(current->mm); + return 0; +} + +static int kvm_s2_fault_pin_pfn(struct kvm_s2_fault *fault) +{ + int ret; + + ret = kvm_s2_fault_get_vma_info(fault); + if (ret) + return ret; + fault->pfn = __kvm_faultin_pfn(fault->memslot, fault->gfn, fault->write_fault ? FOLL_WRITE : 0, &fault->writable, &fault->page); -- 2.53.0.473.g4a7958ca14-goog