Page 1 of 1

Dirty COW

Posted: Sat Oct 22, 2016 8:26 pm
by gexcite
Patch dla gentoo-sources-4.4.21 - gdyby ktoś potrzebował :-)
U mnie działa

Code: Select all

diff -ruN a/include/linux/mm.h b/include/linux/mm.h
--- a/include/linux/mm.h        2016-10-22 21:50:23.000000000 +0200
+++ b/include/linux/mm.h        2016-10-22 22:07:45.853359937 +0200
@@ -2111,6 +2111,7 @@
 #define FOLL_MIGRATION 0x400   /* wait for page to replace migration entry */
 #define FOLL_TRIED     0x800   /* a retry, previous pass started an IO */
 #define FOLL_MLOCK     0x1000  /* lock present pages */
+#define FOLL_COW       0x4000  /* internal GUP flag */
 
 typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr,
                        void *data);
diff -ruN a/mm/gup.c b/mm/gup.c
--- a/mm/gup.c  2016-01-11 00:01:32.000000000 +0100
+++ b/mm/gup.c  2016-10-22 22:12:01.131750073 +0200
@@ -58,6 +58,16 @@
        return -EEXIST;
 }
 
+/*
+ * FOLL_FORCE can write to even unwritable pte's, but only
+ * after we've gone through a COW cycle and they are dirty.
+ */
+static inline bool can_follow_write_pte(pte_t pte, unsigned int flags)
+{
+       return pte_write(pte) ||
+               ((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte));
+}
+
 static struct page *follow_page_pte(struct vm_area_struct *vma,
                unsigned long address, pmd_t *pmd, unsigned int flags)
 {
@@ -92,7 +102,7 @@
        }
        if ((flags & FOLL_NUMA) && pte_protnone(pte))
                goto no_page;
-       if ((flags & FOLL_WRITE) && !pte_write(pte)) {
+       if ((flags & FOLL_WRITE) && !can_follow_write_pte(pte, flags)) {
                pte_unmap_unlock(ptep, ptl);
                return NULL;
        }
@@ -352,7 +362,7 @@
         * reCOWed by userspace write).
         */
        if ((ret & VM_FAULT_WRITE) && !(vma->vm_flags & VM_WRITE))
-               *flags &= ~FOLL_WRITE;
+               *flags |= FOLL_COW;
        return 0;
 }

Posted: Sat Oct 22, 2016 8:58 pm
by sebas86
Prościej będzie zaktualizować do najnowszego stabilnego (4.4.26): https://bugs.gentoo.org/show_bug.cgi?id=597738