[PATCH 6.18.y] userfaultfd: prevent registration of special VMAs
Sasha Levin <[email protected]>
| Newsgroups | org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
From: "Mike Rapoport (Microsoft)" <[email protected]> [ Upstream commit 3c58f641e813c3c71039f8fd4d4e2a3aab713288 ] Vova Tokarev says: userfaultfd allows registration on shadow stack VMAs. With userfaultfd access, you can register on the shadow stack, discard a page ... and inject a page with chosen return addresses via UFFDIO_COPY. Update vma_can_userfault() to reject VM_SHADOW_STACK. While on it, also reject VM_SPECIAL so that if a driver would implement vm_uffd_ops, it wouldn't be possible to register special VMAs with userfaultfd. Since VM_SPECIAL includes VM_DONTEXPAND which is set but hugetlb, exclude hugetlb VMAs from the check for VM_SPECIAL. Link: https://lore.kernel.org/[email protected] Fixes: 54007f818206 ("mm: Introduce VM_SHADOW_STACK for shadow stack memory") Signed-off-by: Mike Rapoport (Microsoft) <[email protected]> Reported-by: vova tokarev <[email protected]> Acked-by: David Hildenbrand (Arm) <[email protected]> Reviewed-by: Lorenzo Stoakes <[email protected]> Cc: Al Viro <[email protected]> Cc: Christian Brauner <[email protected]> Cc: Jan Kara <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Mike Rapoport <[email protected]> Cc: Oleg Nesterov <[email protected]> Cc: Peter Xu <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Sasha Levin <[email protected]> --- include/linux/userfaultfd_k.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h index c0e716aec26aa..796a380664bd8 100644 --- a/include/linux/userfaultfd_k.h +++ b/include/linux/userfaultfd_k.h @@ -214,7 +214,10 @@ static inline bool vma_can_userfault(struct vm_area_struct *vma, { vm_flags &= __VM_UFFD_FLAGS; - if (vma->vm_flags & VM_DROPPABLE) + if (vma->vm_flags & (VM_DROPPABLE | VM_SHADOW_STACK)) + return false; + + if (!is_vm_hugetlb_page(vma) && (vma->vm_flags & VM_SPECIAL)) return false; if ((vm_flags & VM_UFFD_MINOR) && -- 2.53.0