Re: [PATCH RFC v4 05/12] mm/gup: add get_user_page_vma() to fault in a page under a held lock

From: John Hubbard

Date: Mon Jul 27 2026 - 22:47:59 EST


On 7/24/26 3:29 PM, Rik van Riel wrote:
...
> +struct page *get_user_page_vma(struct vm_area_struct *vma, unsigned long addr,
...
> + ret = check_vma_flags(vma, gup_flags, VM_IO | VM_PFNMAP);
> + if (ret)
> + goto fail;
> + pfnmap = vma->vm_flags & (VM_IO | VM_PFNMAP);

This treats VM_IO and VM_PFNMAP as the same exception, but they have
different meanings. VM_IO tells MM callers not to inspect the mapped
pages because accesses can have side effects. It does not imply that
the VMA contains raw PFNs!

For example, sg_mmap() creates a VM_IO-only VMA whose fault handler
installs ordinary pages from the SCSI reserve buffer. If such a page is
already present, follow_page_mask() returns it before the pfnmap test
below is reached. Patch 6 then lets /proc/PID/mem and ptrace copy that
page directly, even though sg provides no ->access callback and the
operation fails today. Writes can also modify the buffer when the
mapping is writable. Existing ptrace authorization still applies, so
this is not a privilege bypass, but it removes the VM_IO exclusion for
a driver that did not opt in through ->access.

An untouched page in the same VMA still fails because pfnmap is also
true for VM_IO and this function refuses to fault it. The result
therefore depends on whether the target previously touched the page.
The required exception is narrower. A remap_pfn_range() VMA has both
VM_IO and VM_PFNMAP, but VM_PFNMAP is what identifies the mapping whose
COWed page should be returned.

So if you use the FOLL_PFNMAP_COW flag suggested on patch 4, and test
only VM_PFNMAP here:

ret = check_vma_flags(vma, gup_flags);
if (ret)
goto fail;
pfnmap = vma->vm_flags & VM_PFNMAP;

Patch 6 can set FOLL_PFNMAP_COW for __access_remote_vm().
check_vma_flags() then permits VM_IO | VM_PFNMAP for that caller while
continuing to reject VM_IO-only mappings. vm_normal_page() supplies the
remaining distinction: it returns the COWed normal page and rejects the
raw PFN.

Something like that.

thanks,
--
John Hubbard