diff options
author | Kefeng Wang <wangkefeng.wang@huawei.com> | 2024-10-28 22:56:56 +0800 |
---|---|---|
committer | Andrew Morton <akpm@linux-foundation.org> | 2024-12-18 19:04:42 -0800 |
commit | f5d09de9f1bf9674c6418ff10d0a40cfe29268e1 (patch) | |
tree | e04a8448059128b36640208d44d046fa71e9c526 /mm/memory.c | |
parent | 8aca2bc96c833ba695ede7a45ad7784c836a262e (diff) | |
download | linux-f5d09de9f1bf9674c6418ff10d0a40cfe29268e1.tar.gz linux-f5d09de9f1bf9674c6418ff10d0a40cfe29268e1.tar.bz2 linux-f5d09de9f1bf9674c6418ff10d0a40cfe29268e1.zip |
mm: use aligned address in copy_user_gigantic_page()
In current kernel, hugetlb_wp() calls copy_user_large_folio() with the
fault address. Where the fault address may be not aligned with the huge
page size. Then, copy_user_large_folio() may call
copy_user_gigantic_page() with the address, while
copy_user_gigantic_page() requires the address to be huge page size
aligned. So, this may cause memory corruption or information leak,
addtional, use more obvious naming 'addr_hint' instead of 'addr' for
copy_user_gigantic_page().
Link: https://lkml.kernel.org/r/20241028145656.932941-2-wangkefeng.wang@huawei.com
Fixes: 530dd9926dc1 ("mm: memory: improve copy_user_large_folio()")
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Cc: Huang Ying <ying.huang@intel.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'mm/memory.c')
-rw-r--r-- | mm/memory.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/mm/memory.c b/mm/memory.c index 84864387f965..209885a4134f 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -6852,13 +6852,14 @@ void folio_zero_user(struct folio *folio, unsigned long addr_hint) } static int copy_user_gigantic_page(struct folio *dst, struct folio *src, - unsigned long addr, + unsigned long addr_hint, struct vm_area_struct *vma, unsigned int nr_pages) { - int i; + unsigned long addr = ALIGN_DOWN(addr_hint, folio_size(dst)); struct page *dst_page; struct page *src_page; + int i; for (i = 0; i < nr_pages; i++) { dst_page = folio_page(dst, i); |