mm/core: Do not enforce PKEY permissions on remote mm access
[cascardo/linux.git] / mm / ksm.c
index ca6d2a0..b99e828 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -352,13 +352,17 @@ static inline bool ksm_test_exit(struct mm_struct *mm)
 /*
  * We use break_ksm to break COW on a ksm page: it's a stripped down
  *
- *     if (get_user_pages(current, mm, addr, 1, 1, 1, &page, NULL) == 1)
+ *     if (get_user_pages(addr, 1, 1, 1, &page, NULL) == 1)
  *             put_page(page);
  *
  * but taking great care only to touch a ksm page, in a VM_MERGEABLE vma,
  * in case the application has unmapped and remapped mm,addr meanwhile.
  * Could a ksm page appear anywhere else?  Actually yes, in a VM_PFNMAP
  * mmap of /dev/mem or /dev/kmem, where we would not want to touch it.
+ *
+ * FAULT_FLAG/FOLL_REMOTE are because we do this outside the context
+ * of the process that owns 'vma'.  We also do not want to enforce
+ * protection keys here anyway.
  */
 static int break_ksm(struct vm_area_struct *vma, unsigned long addr)
 {
@@ -367,12 +371,14 @@ static int break_ksm(struct vm_area_struct *vma, unsigned long addr)
 
        do {
                cond_resched();
-               page = follow_page(vma, addr, FOLL_GET | FOLL_MIGRATION);
+               page = follow_page(vma, addr,
+                               FOLL_GET | FOLL_MIGRATION | FOLL_REMOTE);
                if (IS_ERR_OR_NULL(page))
                        break;
                if (PageKsm(page))
                        ret = handle_mm_fault(vma->vm_mm, vma, addr,
-                                                       FAULT_FLAG_WRITE);
+                                                       FAULT_FLAG_WRITE |
+                                                       FAULT_FLAG_REMOTE);
                else
                        ret = VM_FAULT_WRITE;
                put_page(page);