Commit 5934b1be authored by Matthew Wilcox (Oracle)'s avatar Matthew Wilcox (Oracle) Committed by Vlastimil Babka
Browse files

usercopy: Remove folio references from check_heap_object()



Use page_slab() instead of virt_to_folio() followed by folio_slab().
We do end up calling compound_head() twice for non-slab copies, but that
will not be a problem once we allocate memdescs separately.

Signed-off-by: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
Cc: Kees Cook <kees@kernel.org>
Cc: Gustavo A. R. Silva <gustavoars@kernel.org>
Cc: linux-hardening@vger.kernel.org
Link: https://patch.msgid.link/20251113000932.1589073-14-willy@infradead.org


Reviewed-by: default avatarHarry Yoo <harry.yoo@oracle.com>
Reviewed-by: default avatarKees Cook <kees@kernel.org>
Signed-off-by: default avatarVlastimil Babka <vbabka@suse.cz>
parent 025f5b87
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -164,7 +164,8 @@ static inline void check_heap_object(const void *ptr, unsigned long n,
{
	unsigned long addr = (unsigned long)ptr;
	unsigned long offset;
	struct folio *folio;
	struct page *page;
	struct slab *slab;

	if (is_kmap_addr(ptr)) {
		offset = offset_in_page(ptr);
@@ -189,16 +190,23 @@ static inline void check_heap_object(const void *ptr, unsigned long n,
	if (!virt_addr_valid(ptr))
		return;

	folio = virt_to_folio(ptr);

	if (folio_test_slab(folio)) {
	page = virt_to_page(ptr);
	slab = page_slab(page);
	if (slab) {
		/* Check slab allocator for flags and size. */
		__check_heap_object(ptr, n, folio_slab(folio), to_user);
	} else if (folio_test_large(folio)) {
		offset = ptr - folio_address(folio);
		if (n > folio_size(folio) - offset)
		__check_heap_object(ptr, n, slab, to_user);
	} else if (PageCompound(page)) {
		page = compound_head(page);
		offset = ptr - page_address(page);
		if (n > page_size(page) - offset)
			usercopy_abort("page alloc", NULL, to_user, offset, n);
	}

	/*
	 * We cannot check non-compound pages.  They might be part of
	 * a large allocation, in which case crossing a page boundary
	 * is fine.
	 */
}

DEFINE_STATIC_KEY_MAYBE_RO(CONFIG_HARDENED_USERCOPY_DEFAULT_ON,