userfaultfd: shmem/hugetlbfs: only allow to register VM_MAYWRITE vmas
Subsystems (4)
[email protected]
maintainerPATCH 13/31 userfaultfd: shmem/hugetlbfs: only allow to register VM_MAYWRITE vmas
From: Andrea Arcangeli <[email protected]>
Subject: userfaultfd: shmem/hugetlbfs: only allow to register VM_MAYWRITE vmas
After the VMA to register the uffd onto is found, check that it has VM_MAYWRITE set before allowing registration. This way we inherit all common code checks before allowing to fill file holes in shmem and hugetlbfs with UFFDIO_COPY.
The userfaultfd memory model is not applicable for readonly files unless it's a MAP_PRIVATE.
Fixes ff62a3421044 ("hugetlb: implement memfd sealing")
Signed-off-by Andrea Arcangeli <[email protected]>
Reviewed-by Mike Rapoport <[email protected]>
Reviewed-by Hugh Dickins <[email protected]>
Reported-by Jann Horn <[email protected]>
Fixes 4c27fe4c4c84 ("userfaultfd: shmem: add shmem_mcopy_atomic_pte for userfaultfd support")
Cc <[email protected]>
Cc "Dr. David Alan Gilbert" <[email protected]>
Cc Mike Kravetz <[email protected]>
Cc Peter Xu <[email protected]>
Signed-off-by Andrew Morton <[email protected]>
---
fs/userfaultfd.c | 15 +++++++++++++++ mm/userfaultfd.c | 15 ++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-)
fs/userfaultfd.c renamed from fs/userfaultfd.c~userfaultfd-shmem-hugetlbfs-only-allow-to-register-vm_maywrite-vmas +15 -0
@@ -1361,6 +1361,19 @@ static int userfaultfd_register(struct u ret = -EINVAL ;if (!vma_can_userfault (cur)) goto out_unlock; + +/* +* UFFDIO_COPY will fill file holes even without +* PROT_WRITE. This check enforces that if this is a +* MAP_SHARED, the process has write permission to the backing +* file. If VM_MAYWRITE is set it also enforces that on a +* MAP_SHARED vma: there is no F_WRITE_SEAL and no further +* F_WRITE_SEAL can be taken until the vma is destroyed. +*/ + ret = -EPERM ; +if (unlikely (!(cur->vm_flags &VM_MAYWRITE ))) + goto out_unlock; +/* * If this vma contains ending address, and huge pages * check alignment.
@@ -1406,6 +1419,7 @@ static int userfaultfd_register(struct uBUG_ON (!vma_can_userfault (vma));BUG_ON (vma->vm_userfaultfd_ctx.ctx && vma->vm_userfaultfd_ctx.ctx != ctx); +WARN_ON (!(vma->vm_flags &VM_MAYWRITE ));/* * Nothing to do: this vma is already registered into this
@@ -1552,6 +1566,7 @@ static int userfaultfd_unregister(structcond_resched ();BUG_ON (!vma_can_userfault (vma)); +WARN_ON (!(vma->vm_flags &VM_MAYWRITE ));/* * Nothing to do: this vma is already registered into this
mm/userfaultfd.c renamed from mm/userfaultfd.c~userfaultfd-shmem-hugetlbfs-only-allow-to-register-vm_maywrite-vmas +6 -9
@@ -205,8 +205,9 @@ retry:if (!dst_vma || !is_vm_hugetlb_page (dst_vma)) goto out_unlock;/* -* Only allow __mcopy_atomic_hugetlb on userfaultfd -* registered ranges. +* Check the vma is registered in uffd, this is +* required to enforce the VM_MAYWRITE check done at +* uffd registration time. */ if (!dst_vma->vm_userfaultfd_ctx.ctx) goto out_unlock;
@@ -459,13 +460,9 @@ retry:if (!dst_vma) goto out_unlock;/* -* Be strict and only allow __mcopy_atomic on userfaultfd -* registered ranges to prevent userland errors going -* unnoticed. As far as the VM consistency is concerned, it -* would be perfectly safe to remove this check, but there's -* no useful usage for __mcopy_atomic ouside of userfaultfd -* registered ranges. This is after all why these are ioctls -* belonging to the userfaultfd and not syscalls. +* Check the vma is registered in uffd, this is required to +* enforce the VM_MAYWRITE check done at uffd registration +* time. */ if (!dst_vma->vm_userfaultfd_ctx.ctx) goto out_unlock;
_