Home Home > GIT Browse > openSUSE-15.0
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVlastimil Babka <vbabka@suse.cz>2018-12-07 14:58:25 +0100
committerVlastimil Babka <vbabka@suse.cz>2018-12-07 15:07:07 +0100
commita2c856b204bc92ea7a2d143fd99e62f826275f5d (patch)
tree36c9e2357ba52863603653149ed5be132673ca52
parentc023f7cd2e16eea5ecec3e5c2a035dfefd154ede (diff)
userfaultfd: shmem: UFFDIO_COPY: set the page dirty if VM_WRITE
is not set (CVE-2018-18397, bsc#1117656).
-rw-r--r--patches.fixes/userfaultfd-shmem-uffdio_copy-set-the-page-dirty-if-vm_write-is-not-set.patch62
-rw-r--r--series.conf1
2 files changed, 63 insertions, 0 deletions
diff --git a/patches.fixes/userfaultfd-shmem-uffdio_copy-set-the-page-dirty-if-vm_write-is-not-set.patch b/patches.fixes/userfaultfd-shmem-uffdio_copy-set-the-page-dirty-if-vm_write-is-not-set.patch
new file mode 100644
index 0000000000..0b237f2f0e
--- /dev/null
+++ b/patches.fixes/userfaultfd-shmem-uffdio_copy-set-the-page-dirty-if-vm_write-is-not-set.patch
@@ -0,0 +1,62 @@
+From: Andrea Arcangeli <aarcange@redhat.com>
+Date: Fri, 30 Nov 2018 14:09:43 -0800
+Subject: userfaultfd: shmem: UFFDIO_COPY: set the page dirty if VM_WRITE is
+ not set
+Git-commit: dcf7fe9d89763a28e0f43975b422ff141fe79e43
+Patch-mainline: v4.20-rc5
+References: CVE-2018-18397, bsc#1117656
+
+Set the page dirty if VM_WRITE is not set because in such case the pte
+won't be marked dirty and the page would be reclaimed without writepage
+(i.e. swapout in the shmem case).
+
+This was found by source review. Most apps (certainly including QEMU)
+only use UFFDIO_COPY on PROT_READ|PROT_WRITE mappings or the app can't
+modify the memory in the first place. This is for correctness and it
+could help the non cooperative use case to avoid unexpected data loss.
+
+Link: http://lkml.kernel.org/r/20181126173452.26955-6-aarcange@redhat.com
+Reviewed-by: Hugh Dickins <hughd@google.com>
+Cc: stable@vger.kernel.org
+Fixes: 4c27fe4c4c84 ("userfaultfd: shmem: add shmem_mcopy_atomic_pte for userfaultfd support")
+Reported-by: Hugh Dickins <hughd@google.com>
+Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
+Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Cc: Jann Horn <jannh@google.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Mike Rapoport <rppt@linux.ibm.com>
+Cc: Peter Xu <peterx@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
+---
+ mm/shmem.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -2298,6 +2298,16 @@ int shmem_mcopy_atomic_pte(struct mm_str
+ _dst_pte = mk_pte(page, dst_vma->vm_page_prot);
+ if (dst_vma->vm_flags & VM_WRITE)
+ _dst_pte = pte_mkwrite(pte_mkdirty(_dst_pte));
++ else {
++ /*
++ * We don't set the pte dirty if the vma has no
++ * VM_WRITE permission, so mark the page dirty or it
++ * could be freed from under us. We could do it
++ * unconditionally before unlock_page(), but doing it
++ * only if VM_WRITE is not set is faster.
++ */
++ set_page_dirty(page);
++ }
+
+ dst_pte = pte_offset_map_lock(dst_mm, dst_pmd, dst_addr, &ptl);
+
+@@ -2331,6 +2341,7 @@ out:
+ return ret;
+ out_release_uncharge_unlock:
+ pte_unmap_unlock(dst_pte, ptl);
++ ClearPageDirty(page);
+ delete_from_page_cache(page);
+ out_release_uncharge:
+ mem_cgroup_cancel_charge(page, memcg, false);
diff --git a/series.conf b/series.conf
index 7b8c557099..3c8925019a 100644
--- a/series.conf
+++ b/series.conf
@@ -19047,6 +19047,7 @@
patches.fixes/userfaultfd-shmem-allocate-anonymous-memory-for-map_private-shmem.patch
patches.fixes/userfaultfd-shmem-hugetlbfs-only-allow-to-register-vm_maywrite-vmas.patch
patches.fixes/userfaultfd-shmem-add-i_size-checks.patch
+ patches.fixes/userfaultfd-shmem-uffdio_copy-set-the-page-dirty-if-vm_write-is-not-set.patch
patches.drivers/pci-imx6-fix-link-training-status-detection-in-link-up-check
patches.fixes/nvme-free-ctrl-device-name-on-init-failure.patch
patches.fixes/0001-xen-x86-add-diagnostic-printout-to-xen_mc_flush-in-c.patch