linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] mm/gup: handle NULL pages in unpin_user_pages()
@ 2024-11-21  3:49 John Hubbard
  2024-11-21  8:11 ` David Hildenbrand
  0 siblings, 1 reply; 2+ messages in thread
From: John Hubbard @ 2024-11-21  3:49 UTC (permalink / raw)
  To: Andrew Morton
  Cc: LKML, linux-mm, John Hubbard, David Hildenbrand, Oscar Salvador,
	Vivek Kasireddy, Dave Airlie, Gerd Hoffmann, Matthew Wilcox,
	Christoph Hellwig, Jason Gunthorpe, Peter Xu, Arnd Bergmann,
	Daniel Vetter, Dongwon Kim, Hugh Dickins, Junxiao Chang, stable

The recent addition of "pofs" (pages or folios) handling to gup has a
flaw: it assumes that unpin_user_pages() handles NULL pages in the
pages** array. That's not the case, as I discovered when I ran on a new
configuration on my test machine.

Fix this by skipping NULL pages in unpin_user_pages(), just like
unpin_folios() already does.

Details: when booting on x86 with "numa=fake=2 movablecore=4G" on Linux
6.12, and running this:

    tools/testing/selftests/mm/gup_longterm

...I get the following crash:

BUG: kernel NULL pointer dereference, address: 0000000000000008
RIP: 0010:sanity_check_pinned_pages+0x3a/0x2d0
...
Call Trace:
 <TASK>
 ? __die_body+0x66/0xb0
 ? page_fault_oops+0x30c/0x3b0
 ? do_user_addr_fault+0x6c3/0x720
 ? irqentry_enter+0x34/0x60
 ? exc_page_fault+0x68/0x100
 ? asm_exc_page_fault+0x22/0x30
 ? sanity_check_pinned_pages+0x3a/0x2d0
 unpin_user_pages+0x24/0xe0
 check_and_migrate_movable_pages_or_folios+0x455/0x4b0
 __gup_longterm_locked+0x3bf/0x820
 ? mmap_read_lock_killable+0x12/0x50
 ? __pfx_mmap_read_lock_killable+0x10/0x10
 pin_user_pages+0x66/0xa0
 gup_test_ioctl+0x358/0xb20
 __se_sys_ioctl+0x6b/0xc0
 do_syscall_64+0x7b/0x150
 entry_SYSCALL_64_after_hwframe+0x76/0x7e

Fixes: 94efde1d1539 ("mm/gup: avoid an unnecessary allocation call for FOLL_LONGTERM cases")
Cc: David Hildenbrand <david@redhat.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Vivek Kasireddy <vivek.kasireddy@intel.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Jason Gunthorpe <jgg@nvidia.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Dongwon Kim <dongwon.kim@intel.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Junxiao Chang <junxiao.chang@intel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
---

Hi,

This is based on v6.12.

Changes since v1:

Simplified by limiting the change to unpin_user_pages() and the
associated sanity_check_pinned_pages(), thanks to David Hildenbrand
for pointing out that issue in v1 [1].

[1] https://lore.kernel.org/20241119044923.194853-1-jhubbard@nvidia.com

thanks,
John Hubbard




 mm/gup.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/mm/gup.c b/mm/gup.c
index ad0c8922dac3..7053f8114e01 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -52,7 +52,12 @@ static inline void sanity_check_pinned_pages(struct page **pages,
 	 */
 	for (; npages; npages--, pages++) {
 		struct page *page = *pages;
-		struct folio *folio = page_folio(page);
+		struct folio *folio;
+
+		if (!page)
+			continue;
+
+		folio = page_folio(page);
 
 		if (is_zero_page(page) ||
 		    !folio_test_anon(folio))
@@ -409,6 +414,10 @@ void unpin_user_pages(struct page **pages, unsigned long npages)
 
 	sanity_check_pinned_pages(pages, npages);
 	for (i = 0; i < npages; i += nr) {
+		if (!pages[i]) {
+			nr = 1;
+			continue;
+		}
 		folio = gup_folio_next(pages, npages, i, &nr);
 		gup_put_folio(folio, nr, FOLL_PIN);
 	}

base-commit: adc218676eef25575469234709c2d87185ca223a
-- 
2.47.0



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] mm/gup: handle NULL pages in unpin_user_pages()
  2024-11-21  3:49 [PATCH v2] mm/gup: handle NULL pages in unpin_user_pages() John Hubbard
@ 2024-11-21  8:11 ` David Hildenbrand
  0 siblings, 0 replies; 2+ messages in thread
From: David Hildenbrand @ 2024-11-21  8:11 UTC (permalink / raw)
  To: John Hubbard, Andrew Morton
  Cc: LKML, linux-mm, Oscar Salvador, Vivek Kasireddy, Dave Airlie,
	Gerd Hoffmann, Matthew Wilcox, Christoph Hellwig,
	Jason Gunthorpe, Peter Xu, Arnd Bergmann, Daniel Vetter,
	Dongwon Kim, Hugh Dickins, Junxiao Chang, stable

On 21.11.24 04:49, John Hubbard wrote:
> The recent addition of "pofs" (pages or folios) handling to gup has a
> flaw: it assumes that unpin_user_pages() handles NULL pages in the
> pages** array. That's not the case, as I discovered when I ran on a new
> configuration on my test machine.
> 
> Fix this by skipping NULL pages in unpin_user_pages(), just like
> unpin_folios() already does.
> 
> Details: when booting on x86 with "numa=fake=2 movablecore=4G" on Linux
> 6.12, and running this:
> 
>      tools/testing/selftests/mm/gup_longterm
> 
> ...I get the following crash:
> 
> BUG: kernel NULL pointer dereference, address: 0000000000000008
> RIP: 0010:sanity_check_pinned_pages+0x3a/0x2d0
> ...
> Call Trace:
>   <TASK>
>   ? __die_body+0x66/0xb0
>   ? page_fault_oops+0x30c/0x3b0
>   ? do_user_addr_fault+0x6c3/0x720
>   ? irqentry_enter+0x34/0x60
>   ? exc_page_fault+0x68/0x100
>   ? asm_exc_page_fault+0x22/0x30
>   ? sanity_check_pinned_pages+0x3a/0x2d0
>   unpin_user_pages+0x24/0xe0
>   check_and_migrate_movable_pages_or_folios+0x455/0x4b0
>   __gup_longterm_locked+0x3bf/0x820
>   ? mmap_read_lock_killable+0x12/0x50
>   ? __pfx_mmap_read_lock_killable+0x10/0x10
>   pin_user_pages+0x66/0xa0
>   gup_test_ioctl+0x358/0xb20
>   __se_sys_ioctl+0x6b/0xc0
>   do_syscall_64+0x7b/0x150
>   entry_SYSCALL_64_after_hwframe+0x76/0x7e
> 
> Fixes: 94efde1d1539 ("mm/gup: avoid an unnecessary allocation call for FOLL_LONGTERM cases")
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Oscar Salvador <osalvador@suse.de>
> Cc: Vivek Kasireddy <vivek.kasireddy@intel.com>
> Cc: Dave Airlie <airlied@redhat.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Matthew Wilcox <willy@infradead.org>
> Cc: Christoph Hellwig <hch@infradead.org>
> Cc: Jason Gunthorpe <jgg@nvidia.com>
> Cc: Peter Xu <peterx@redhat.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Cc: Dongwon Kim <dongwon.kim@intel.com>
> Cc: Hugh Dickins <hughd@google.com>
> Cc: Junxiao Chang <junxiao.chang@intel.com>
> Cc: <stable@vger.kernel.org>
> Signed-off-by: John Hubbard <jhubbard@nvidia.com>
> ---

Thanks!

Acked-by: David Hildenbrand <david@redhat.com>

-- 
Cheers,

David / dhildenb



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-11-21  8:11 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-11-21  3:49 [PATCH v2] mm/gup: handle NULL pages in unpin_user_pages() John Hubbard
2024-11-21  8:11 ` David Hildenbrand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox