| From 7c25a0b89a487878b0691e6524fb5a8827322194 Mon Sep 17 00:00:00 2001 |
| From: Muchun Song <songmuchun@bytedance.com> |
| Date: Tue, 22 Mar 2022 14:42:08 -0700 |
| Subject: mm: userfaultfd: fix missing cache flush in mcopy_atomic_pte() and __mcopy_atomic() |
| |
| From: Muchun Song <songmuchun@bytedance.com> |
| |
| commit 7c25a0b89a487878b0691e6524fb5a8827322194 upstream. |
| |
| userfaultfd calls mcopy_atomic_pte() and __mcopy_atomic() which do not |
| do any cache flushing for the target page. Then the target page will be |
| mapped to the user space with a different address (user address), which |
| might have an alias issue with the kernel address used to copy the data |
| from the user to. Fix this by insert flush_dcache_page() after |
| copy_from_user() succeeds. |
| |
| Link: https://lkml.kernel.org/r/20220210123058.79206-7-songmuchun@bytedance.com |
| Fixes: b6ebaedb4cb1 ("userfaultfd: avoid mmap_sem read recursion in mcopy_atomic") |
| Fixes: c1a4de99fada ("userfaultfd: mcopy_atomic|mfill_zeropage: UFFDIO_COPY|UFFDIO_ZEROPAGE preparation") |
| Signed-off-by: Muchun Song <songmuchun@bytedance.com> |
| Cc: Axel Rasmussen <axelrasmussen@google.com> |
| Cc: David Rientjes <rientjes@google.com> |
| Cc: Fam Zheng <fam.zheng@bytedance.com> |
| Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> |
| Cc: Lars Persson <lars.persson@axis.com> |
| Cc: Mike Kravetz <mike.kravetz@oracle.com> |
| Cc: Peter Xu <peterx@redhat.com> |
| Cc: Xiongchun Duan <duanxiongchun@bytedance.com> |
| Cc: Zi Yan <ziy@nvidia.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| mm/userfaultfd.c | 3 +++ |
| 1 file changed, 3 insertions(+) |
| |
| --- a/mm/userfaultfd.c |
| +++ b/mm/userfaultfd.c |
| @@ -151,6 +151,8 @@ static int mcopy_atomic_pte(struct mm_st |
| /* don't free the page */ |
| goto out; |
| } |
| + |
| + flush_dcache_page(page); |
| } else { |
| page = *pagep; |
| *pagep = NULL; |
| @@ -621,6 +623,7 @@ retry: |
| err = -EFAULT; |
| goto out; |
| } |
| + flush_dcache_page(page); |
| goto retry; |
| } else |
| BUG_ON(page); |