ANDROID: Use the notifier lock to perform file-backed vma teardown

When a file-backed vma is being released, the userspace can have an
expectation that the vma and the file it's pinning will be released
synchronously. This does not happen when SPF is enabled because vma
and associated file are released asynchronously after RCU grace
period. This is done to prevent pagefault handler from stepping on
a deleted object. Fix this issue by synchronizing the file-backed
pagefault handler with the vma tear-down using notifier lock.

Fixes: 48e35d053f "FROMLIST: mm: rcu safe vma->vm_file freeing"
Bug: 231394031
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Change-Id: Idabf44b8e5a91805e99d79884af77a000dca7637
This commit is contained in:
Suren Baghdasaryan 2022-05-13 11:07:14 -07:00
parent d3616c7e0b
commit dc8ac508af
2 changed files with 16 additions and 3 deletions

View File

@ -402,6 +402,13 @@ void vm_area_free(struct vm_area_struct *vma)
free_anon_vma_name(vma);
#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
if (atomic_read(&vma->vm_mm->mm_users) > 1) {
if (vma->vm_file) {
struct mm_struct *mm = vma->vm_mm;
percpu_down_write(mm->mmu_notifier_lock);
____vm_area_free(vma);
percpu_up_write(mm->mmu_notifier_lock);
return;
}
call_rcu(&vma->vm_rcu, __vm_area_free);
return;
}

View File

@ -3988,10 +3988,16 @@ static vm_fault_t __do_fault(struct vm_fault *vmf)
/*
* The mmap sequence count check guarantees that the
* vma we fetched at the start of the fault was still
* current at that point in time. The rcu read lock
* ensures vmf->vma->vm_file stays valid.
* current at that point in time. The notifier lock
* ensures vmf->vma->vm_file stays valid. vma is
* stable because we are operating on a copy made at
* the start of the fault.
*/
ret = vma->vm_ops->fault(vmf);
if (mmu_notifier_trylock(vmf->vma->vm_mm)) {
ret = vma->vm_ops->fault(vmf);
mmu_notifier_unlock(vmf->vma->vm_mm);
} else
ret = VM_FAULT_RETRY;
}
rcu_read_unlock();
} else