From: Greg Kroah-Hartman Date: Mon, 16 Dec 2019 15:47:38 +0000 (+0100) Subject: drop mm-memory.c-fix-a-huge-pud-insertion-race-during-faulting.patch X-Git-Tag: v5.4.4~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=39a132933427c709ea684a2dd4aa4556ff84ecf3;p=thirdparty%2Fkernel%2Fstable-queue.git drop mm-memory.c-fix-a-huge-pud-insertion-race-during-faulting.patch --- diff --git a/queue-5.3/mm-memory.c-fix-a-huge-pud-insertion-race-during-faulting.patch b/queue-5.3/mm-memory.c-fix-a-huge-pud-insertion-race-during-faulting.patch deleted file mode 100644 index e2991cd68a3..00000000000 --- a/queue-5.3/mm-memory.c-fix-a-huge-pud-insertion-race-during-faulting.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 625110b5e9dae9074d8a7e67dd07f821a053eed7 Mon Sep 17 00:00:00 2001 -From: Thomas Hellstrom -Date: Sat, 30 Nov 2019 17:51:32 -0800 -Subject: mm/memory.c: fix a huge pud insertion race during faulting - -From: Thomas Hellstrom - -commit 625110b5e9dae9074d8a7e67dd07f821a053eed7 upstream. - -A huge pud page can theoretically be faulted in racing with pmd_alloc() -in __handle_mm_fault(). That will lead to pmd_alloc() returning an -invalid pmd pointer. - -Fix this by adding a pud_trans_unstable() function similar to -pmd_trans_unstable() and check whether the pud is really stable before -using the pmd pointer. - -Race: - Thread 1: Thread 2: Comment - create_huge_pud() Fallback - not taken. - create_huge_pud() Taken. - pmd_alloc() Returns an invalid pointer. - -This will result in user-visible huge page data corruption. - -Note that this was caught during a code audit rather than a real -experienced problem. It looks to me like the only implementation that -currently creates huge pud pagetable entries is dev_dax_huge_fault() -which doesn't appear to care much about private (COW) mappings or -write-tracking which is, I believe, a prerequisite for create_huge_pud() -falling back on thread 1, but not in thread 2. - -Link: http://lkml.kernel.org/r/20191115115808.21181-2-thomas_os@shipmail.org -Fixes: a00cc7d9dd93 ("mm, x86: add support for PUD-sized transparent hugepages") -Signed-off-by: Thomas Hellstrom -Acked-by: Kirill A. Shutemov -Cc: Arnd Bergmann -Cc: Matthew Wilcox -Cc: -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman - ---- - include/asm-generic/pgtable.h | 25 +++++++++++++++++++++++++ - mm/memory.c | 6 ++++++ - 2 files changed, 31 insertions(+) - ---- a/include/asm-generic/pgtable.h -+++ b/include/asm-generic/pgtable.h -@@ -912,6 +912,31 @@ static inline int pud_trans_huge(pud_t p - } - #endif - -+/* See pmd_none_or_trans_huge_or_clear_bad for discussion. */ -+static inline int pud_none_or_trans_huge_or_dev_or_clear_bad(pud_t *pud) -+{ -+ pud_t pudval = READ_ONCE(*pud); -+ -+ if (pud_none(pudval) || pud_trans_huge(pudval) || pud_devmap(pudval)) -+ return 1; -+ if (unlikely(pud_bad(pudval))) { -+ pud_clear_bad(pud); -+ return 1; -+ } -+ return 0; -+} -+ -+/* See pmd_trans_unstable for discussion. */ -+static inline int pud_trans_unstable(pud_t *pud) -+{ -+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && \ -+ defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD) -+ return pud_none_or_trans_huge_or_dev_or_clear_bad(pud); -+#else -+ return 0; -+#endif -+} -+ - #ifndef pmd_read_atomic - static inline pmd_t pmd_read_atomic(pmd_t *pmdp) - { ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -3905,6 +3905,7 @@ static vm_fault_t __handle_mm_fault(stru - vmf.pud = pud_alloc(mm, p4d, address); - if (!vmf.pud) - return VM_FAULT_OOM; -+retry_pud: - if (pud_none(*vmf.pud) && __transparent_hugepage_enabled(vma)) { - ret = create_huge_pud(&vmf); - if (!(ret & VM_FAULT_FALLBACK)) -@@ -3931,6 +3932,11 @@ static vm_fault_t __handle_mm_fault(stru - vmf.pmd = pmd_alloc(mm, vmf.pud, address); - if (!vmf.pmd) - return VM_FAULT_OOM; -+ -+ /* Huge pud page fault raced with pmd_alloc? */ -+ if (pud_trans_unstable(vmf.pud)) -+ goto retry_pud; -+ - if (pmd_none(*vmf.pmd) && __transparent_hugepage_enabled(vma)) { - ret = create_huge_pmd(&vmf); - if (!(ret & VM_FAULT_FALLBACK)) diff --git a/queue-5.3/series b/queue-5.3/series index 4102266522c..2939cb1efed 100644 --- a/queue-5.3/series +++ b/queue-5.3/series @@ -170,7 +170,6 @@ powerpc-avoid-clang-warnings-around-setjmp-and-longj.patch powerpc-fix-vdso-clock_getres.patch mm-memfd-fix-cow-issue-on-map_private-and-f_seal_future_write-mappings.patch mfd-rk808-fix-rk818-id-template.patch -mm-memory.c-fix-a-huge-pud-insertion-race-during-faulting.patch mm-memcg-slab-wait-for-root-kmem_cache-refcnt-killing-on-root-kmem_cache-destruction.patch ext4-work-around-deleting-a-file-with-i_nlink-0-safely.patch firmware-qcom-scm-ensure-a0-status-code-is-treated-as-signed.patch diff --git a/queue-5.4/mm-memory.c-fix-a-huge-pud-insertion-race-during-faulting.patch b/queue-5.4/mm-memory.c-fix-a-huge-pud-insertion-race-during-faulting.patch deleted file mode 100644 index b1a49fa8a0d..00000000000 --- a/queue-5.4/mm-memory.c-fix-a-huge-pud-insertion-race-during-faulting.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 625110b5e9dae9074d8a7e67dd07f821a053eed7 Mon Sep 17 00:00:00 2001 -From: Thomas Hellstrom -Date: Sat, 30 Nov 2019 17:51:32 -0800 -Subject: mm/memory.c: fix a huge pud insertion race during faulting - -From: Thomas Hellstrom - -commit 625110b5e9dae9074d8a7e67dd07f821a053eed7 upstream. - -A huge pud page can theoretically be faulted in racing with pmd_alloc() -in __handle_mm_fault(). That will lead to pmd_alloc() returning an -invalid pmd pointer. - -Fix this by adding a pud_trans_unstable() function similar to -pmd_trans_unstable() and check whether the pud is really stable before -using the pmd pointer. - -Race: - Thread 1: Thread 2: Comment - create_huge_pud() Fallback - not taken. - create_huge_pud() Taken. - pmd_alloc() Returns an invalid pointer. - -This will result in user-visible huge page data corruption. - -Note that this was caught during a code audit rather than a real -experienced problem. It looks to me like the only implementation that -currently creates huge pud pagetable entries is dev_dax_huge_fault() -which doesn't appear to care much about private (COW) mappings or -write-tracking which is, I believe, a prerequisite for create_huge_pud() -falling back on thread 1, but not in thread 2. - -Link: http://lkml.kernel.org/r/20191115115808.21181-2-thomas_os@shipmail.org -Fixes: a00cc7d9dd93 ("mm, x86: add support for PUD-sized transparent hugepages") -Signed-off-by: Thomas Hellstrom -Acked-by: Kirill A. Shutemov -Cc: Arnd Bergmann -Cc: Matthew Wilcox -Cc: -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman - ---- - include/asm-generic/pgtable.h | 25 +++++++++++++++++++++++++ - mm/memory.c | 6 ++++++ - 2 files changed, 31 insertions(+) - ---- a/include/asm-generic/pgtable.h -+++ b/include/asm-generic/pgtable.h -@@ -912,6 +912,31 @@ static inline int pud_trans_huge(pud_t p - } - #endif - -+/* See pmd_none_or_trans_huge_or_clear_bad for discussion. */ -+static inline int pud_none_or_trans_huge_or_dev_or_clear_bad(pud_t *pud) -+{ -+ pud_t pudval = READ_ONCE(*pud); -+ -+ if (pud_none(pudval) || pud_trans_huge(pudval) || pud_devmap(pudval)) -+ return 1; -+ if (unlikely(pud_bad(pudval))) { -+ pud_clear_bad(pud); -+ return 1; -+ } -+ return 0; -+} -+ -+/* See pmd_trans_unstable for discussion. */ -+static inline int pud_trans_unstable(pud_t *pud) -+{ -+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && \ -+ defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD) -+ return pud_none_or_trans_huge_or_dev_or_clear_bad(pud); -+#else -+ return 0; -+#endif -+} -+ - #ifndef pmd_read_atomic - static inline pmd_t pmd_read_atomic(pmd_t *pmdp) - { ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -3914,6 +3914,7 @@ static vm_fault_t __handle_mm_fault(stru - vmf.pud = pud_alloc(mm, p4d, address); - if (!vmf.pud) - return VM_FAULT_OOM; -+retry_pud: - if (pud_none(*vmf.pud) && __transparent_hugepage_enabled(vma)) { - ret = create_huge_pud(&vmf); - if (!(ret & VM_FAULT_FALLBACK)) -@@ -3940,6 +3941,11 @@ static vm_fault_t __handle_mm_fault(stru - vmf.pmd = pmd_alloc(mm, vmf.pud, address); - if (!vmf.pmd) - return VM_FAULT_OOM; -+ -+ /* Huge pud page fault raced with pmd_alloc? */ -+ if (pud_trans_unstable(vmf.pud)) -+ goto retry_pud; -+ - if (pmd_none(*vmf.pmd) && __transparent_hugepage_enabled(vma)) { - ret = create_huge_pmd(&vmf); - if (!(ret & VM_FAULT_FALLBACK)) diff --git a/queue-5.4/series b/queue-5.4/series index 49e468453ad..481db2ebfcf 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -163,7 +163,6 @@ powerpc-avoid-clang-warnings-around-setjmp-and-longj.patch powerpc-fix-vdso-clock_getres.patch mm-memfd-fix-cow-issue-on-map_private-and-f_seal_future_write-mappings.patch mfd-rk808-fix-rk818-id-template.patch -mm-memory.c-fix-a-huge-pud-insertion-race-during-faulting.patch mm-memcg-slab-wait-for-root-kmem_cache-refcnt-killing-on-root-kmem_cache-destruction.patch ext4-work-around-deleting-a-file-with-i_nlink-0-safely.patch firmware-qcom-scm-ensure-a0-status-code-is-treated-as-signed.patch