ANDROID: userfaultfd: Fix use-after-free in userfaultfd_using_sigbus()

In 582c6d188ec1 ("ANDROID: userfaultfd: allow SPF for
UFFD_FEATURE_SIGBUS on private+anon"), we allowed userfaultfd
registered VMAs using SIGBUS to be handled with SPF. But during
page-fault handling, before userfaultfd_ctx is dereferenced,
another thread may call userfaultfd_release(), unlink the VMA
and then deallocate the same userfaultfd_ctx, leaving a dangling
pointer behind for dereference.

It is insufficient to do the access under rcu read-lock as the context
may have been deallocated before entering the critical section. Checking
vma has not changed in the critical section ensures we are not looking at
dangling pointer to userfaultfd_ctx.

Change-Id: I9c3ba0f1352e49f0ea387b92c18b5f1b5dcad7f1
Signed-off-by: Lokesh Gidra <lokeshgidra@google.com>
Bug: 349936398
(cherry picked from commit c75b369e72da0283a20f794c0070c478b490f453)
This commit is contained in:
Lokesh Gidra
2024-06-30 00:31:34 -07:00
parent 441ca240dd
commit 6f61666ab1
5 changed files with 30 additions and 22 deletions

View File

@@ -5058,6 +5058,7 @@ static vm_fault_t ___handle_speculative_fault(struct mm_struct *mm,
vmf.vma_flags = READ_ONCE(vmf.vma->vm_flags);
vmf.vma_page_prot = READ_ONCE(vmf.vma->vm_page_prot);
vmf.sequence = seq;
#ifdef CONFIG_USERFAULTFD
/*
@@ -5067,7 +5068,7 @@ static vm_fault_t ___handle_speculative_fault(struct mm_struct *mm,
if (unlikely(vmf.vma_flags & __VM_UFFD_FLAGS)) {
uffd_missing_sigbus = vma_is_anonymous(vmf.vma) &&
(vmf.vma_flags & VM_UFFD_MISSING) &&
userfaultfd_using_sigbus(vmf.vma);
userfaultfd_using_sigbus(&vmf);
if (!uffd_missing_sigbus) {
trace_spf_vma_notsup(_RET_IP_, vmf.vma, address);
return VM_FAULT_RETRY;
@@ -5193,7 +5194,6 @@ static vm_fault_t ___handle_speculative_fault(struct mm_struct *mm,
vmf.pte = NULL;
}
vmf.sequence = seq;
vmf.flags = flags;
local_irq_enable();