Skip to content

Commit 509b21e

Browse files
aagitjfvogel
authored andcommitted
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. Link: http://lkml.kernel.org/r/[email protected] Fixes: ff62a34 ("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: 4c27fe4 ("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]> Cc: [email protected] Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]> (cherry picked from commit 29ec906) Orabug: 29163742 CVE: CVE-2018-18397 Signed-off-by: Shan Hai <[email protected]> Reviewed-by: Jack Vogel <[email protected]>
1 parent b853527 commit 509b21e

File tree

2 files changed

+21
-9
lines changed

2 files changed

+21
-9
lines changed

fs/userfaultfd.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,19 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
13621362
ret = -EINVAL;
13631363
if (!vma_can_userfault(cur))
13641364
goto out_unlock;
1365+
1366+
/*
1367+
* UFFDIO_COPY will fill file holes even without
1368+
* PROT_WRITE. This check enforces that if this is a
1369+
* MAP_SHARED, the process has write permission to the backing
1370+
* file. If VM_MAYWRITE is set it also enforces that on a
1371+
* MAP_SHARED vma: there is no F_WRITE_SEAL and no further
1372+
* F_WRITE_SEAL can be taken until the vma is destroyed.
1373+
*/
1374+
ret = -EPERM;
1375+
if (unlikely(!(cur->vm_flags & VM_MAYWRITE)))
1376+
goto out_unlock;
1377+
13651378
/*
13661379
* If this vma contains ending address, and huge pages
13671380
* check alignment.
@@ -1407,6 +1420,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
14071420
BUG_ON(!vma_can_userfault(vma));
14081421
BUG_ON(vma->vm_userfaultfd_ctx.ctx &&
14091422
vma->vm_userfaultfd_ctx.ctx != ctx);
1423+
WARN_ON(!(vma->vm_flags & VM_MAYWRITE));
14101424

14111425
/*
14121426
* Nothing to do: this vma is already registered into this
@@ -1553,6 +1567,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
15531567
cond_resched();
15541568

15551569
BUG_ON(!vma_can_userfault(vma));
1570+
WARN_ON(!(vma->vm_flags & VM_MAYWRITE));
15561571

15571572
/*
15581573
* Nothing to do: this vma is already registered into this

mm/userfaultfd.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,9 @@ static __always_inline ssize_t __mcopy_atomic_hugetlb(struct mm_struct *dst_mm,
207207
if (!dst_vma || !is_vm_hugetlb_page(dst_vma))
208208
goto out_unlock;
209209
/*
210-
* Only allow __mcopy_atomic_hugetlb on userfaultfd
211-
* registered ranges.
210+
* Check the vma is registered in uffd, this is
211+
* required to enforce the VM_MAYWRITE check done at
212+
* uffd registration time.
212213
*/
213214
if (!dst_vma->vm_userfaultfd_ctx.ctx)
214215
goto out_unlock;
@@ -446,13 +447,9 @@ static __always_inline ssize_t __mcopy_atomic(struct mm_struct *dst_mm,
446447
if (!dst_vma)
447448
goto out_unlock;
448449
/*
449-
* Be strict and only allow __mcopy_atomic on userfaultfd
450-
* registered ranges to prevent userland errors going
451-
* unnoticed. As far as the VM consistency is concerned, it
452-
* would be perfectly safe to remove this check, but there's
453-
* no useful usage for __mcopy_atomic ouside of userfaultfd
454-
* registered ranges. This is after all why these are ioctls
455-
* belonging to the userfaultfd and not syscalls.
450+
* Check the vma is registered in uffd, this is required to
451+
* enforce the VM_MAYWRITE check done at uffd registration
452+
* time.
456453
*/
457454
if (!dst_vma->vm_userfaultfd_ctx.ctx)
458455
goto out_unlock;

0 commit comments

Comments
 (0)