| From ba7c244dda3be9ccc47b0711921d9f28d7ffdcf4 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 9 Jun 2022 21:08:35 +0800 |
| Subject: lib/test_hmm: avoid accessing uninitialized pages |
| |
| From: Miaohe Lin <linmiaohe@huawei.com> |
| |
| [ Upstream commit ed913b055a74b723976f8e885a3395162a0371e6 ] |
| |
| If make_device_exclusive_range() fails or returns pages marked for |
| exclusive access less than required, remaining fields of pages will left |
| uninitialized. So dmirror_atomic_map() will access those yet |
| uninitialized fields of pages. To fix it, do dmirror_atomic_map() iff all |
| pages are marked for exclusive access (we will break if mapped is less |
| than required anyway) so we won't access those uninitialized fields of |
| pages. |
| |
| Link: https://lkml.kernel.org/r/20220609130835.35110-1-linmiaohe@huawei.com |
| Fixes: b659baea7546 ("mm: selftests for exclusive device memory") |
| Signed-off-by: Miaohe Lin <linmiaohe@huawei.com> |
| Cc: Jerome Glisse <jglisse@redhat.com> |
| Cc: Alistair Popple <apopple@nvidia.com> |
| Cc: Jason Gunthorpe <jgg@ziepe.ca> |
| Cc: Ralph Campbell <rcampbell@nvidia.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| lib/test_hmm.c | 10 ++++++++-- |
| 1 file changed, 8 insertions(+), 2 deletions(-) |
| |
| diff --git a/lib/test_hmm.c b/lib/test_hmm.c |
| index cfe632047839..f2c3015c5c82 100644 |
| --- a/lib/test_hmm.c |
| +++ b/lib/test_hmm.c |
| @@ -732,7 +732,7 @@ static int dmirror_exclusive(struct dmirror *dmirror, |
| |
| mmap_read_lock(mm); |
| for (addr = start; addr < end; addr = next) { |
| - unsigned long mapped; |
| + unsigned long mapped = 0; |
| int i; |
| |
| if (end < addr + (ARRAY_SIZE(pages) << PAGE_SHIFT)) |
| @@ -741,7 +741,13 @@ static int dmirror_exclusive(struct dmirror *dmirror, |
| next = addr + (ARRAY_SIZE(pages) << PAGE_SHIFT); |
| |
| ret = make_device_exclusive_range(mm, addr, next, pages, NULL); |
| - mapped = dmirror_atomic_map(addr, next, pages, dmirror); |
| + /* |
| + * Do dmirror_atomic_map() iff all pages are marked for |
| + * exclusive access to avoid accessing uninitialized |
| + * fields of pages. |
| + */ |
| + if (ret == (next - addr) >> PAGE_SHIFT) |
| + mapped = dmirror_atomic_map(addr, next, pages, dmirror); |
| for (i = 0; i < ret; i++) { |
| if (pages[i]) { |
| unlock_page(pages[i]); |
| -- |
| 2.35.1 |
| |