Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm/uffd: fix vma check on userfault for wp

We used to have a report that pte-marker code can be reached even when
uffd-wp is not compiled in for file memories, here:

https://lore.kernel.org/all/YzeR+R6b4bwBlBHh@x1n/T/#u

I just got time to revisit this and found that the root cause is we simply
messed up with the vma check, so that for !PTE_MARKER_UFFD_WP system, we
will allow UFFDIO_REGISTER of MINOR & WP upon shmem as the check was
wrong:

if (vm_flags & VM_UFFD_MINOR)
return is_vm_hugetlb_page(vma) || vma_is_shmem(vma);

Where we'll allow anything to pass on shmem as long as minor mode is
requested.

Axel did it right when introducing minor mode but I messed it up in
b1f9e876862d when moving code around. Fix it.

Link: https://lkml.kernel.org/r/20221024193336.1233616-1-peterx@redhat.com
Link: https://lkml.kernel.org/r/20221024193336.1233616-2-peterx@redhat.com
Fixes: b1f9e876862d ("mm/uffd: enable write protection for shmem & hugetlbfs")
Signed-off-by: Peter Xu <peterx@redhat.com>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Nadav Amit <nadav.amit@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Peter Xu and committed by
Andrew Morton
67eae54b 5aae9265

+3 -3
+3 -3
include/linux/userfaultfd_k.h
··· 146 146 static inline bool vma_can_userfault(struct vm_area_struct *vma, 147 147 unsigned long vm_flags) 148 148 { 149 - if (vm_flags & VM_UFFD_MINOR) 150 - return is_vm_hugetlb_page(vma) || vma_is_shmem(vma); 151 - 149 + if ((vm_flags & VM_UFFD_MINOR) && 150 + (!is_vm_hugetlb_page(vma) && !vma_is_shmem(vma))) 151 + return false; 152 152 #ifndef CONFIG_PTE_MARKER_UFFD_WP 153 153 /* 154 154 * If user requested uffd-wp but not enabled pte markers for