mirror of
https://github.com/torvalds/linux.git
synced 2026-08-01 20:22:08 +02:00
KVM: arm64: Isolate mmap_read_lock inside new kvm_s2_fault_get_vma_info() helper
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 <tabba@google.com> Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
parent
bae99813c6
commit
f5a5bb8de1
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user